Prioritization Frameworks skill for Codex

RICE, WSJF and Kano scores you can defend. Codex chooses the scoring model that fits the list, fixes scales and anchors before scoring, and records evidence for every input so guesses are visible. A bundled Python script ranks a backlog CSV by RICE, ICE or WSJF and flags near-ties, then a sensitivity check halves the shakiest inputs to show which rankings depend on unvalidated assumptions.

  • Product Management
  • $prioritization-frameworks
  • 144 lines
  • 3 files
  • ~1,600 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- prioritization-frameworks

Installs to ~/.agents/skills/prioritization-frameworks/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $prioritization-frameworks, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Ranks product backlogs and initiative lists with the right scoring model - RICE, ICE, WSJF and cost of delay (CD3), Kano for feature categorization, and MoSCoW for fixed-scope releases - with calibrated scales, evidence for each estimate, sensitivity checks and a bundled script that scores a CSV. Use when asked to prioritize a backlog or feature requests, compare initiatives, run RICE or WSJF scoring, decide what to build next quarter, or explain why one item ranks above another.

Use it when

  • A backlog or initiative list needs an ordered, explainable ranking
  • Stakeholders disagree on what to build next and want a shared model
  • Items have deadlines or decaying value and urgency must be weighed
  • You need to separate must-have features from delighters

Use something else when

  • You are arranging prioritized themes into horizons over time: use roadmap-planning
  • You are sorting a raw inbox of customer feedback first: use feedback-triage

How to check the result

The script runs cleanly, every input cell carries an evidence note or a guess flag, effort came from the team, and the top items survive halving their least certain input.

The mistake it prevents

Adjusting scores until the ranking matches what someone already wanted, instead of recording an explicit override with a reason.

~/.agents/skills/prioritization-frameworks/SKILL.md

--- name: prioritization-frameworks description: Ranks product backlogs and initiative lists with the right scoring model - RICE, ICE, WSJF and cost of delay (CD3), Kano for feature categorization,… license: MIT ---

A ranking is done well when each score rests on stated evidence, scales mean the same thing across items, the top of the list survives reasonable changes to uncertain inputs, and the final order is a decision the owner can defend, not a number they hide behind.

Pick the framework

SituationUseWhy
Product backlog, items with measurable reachRICESeparates audience size from per-user impact; confidence penalizes guesses
Early ideas, growth experiments, little dataICEFast, 1-10 scales; good for weekly experiment triage
Items with deadlines, decaying value, or large size differencesWSJF / cost of delayRewards urgency and small batch size
Deciding which features delight vs are expectedKanoCategorizes, does not rank; run before scoring
Fixed date, must agree scope for one releaseMoSCoWNegotiates scope; useless for ordering a long backlog

Default to RICE for a typical SaaS backlog. Use one framework per list; mixing scores from different models is meaningless.

RICE

score = Reach x Impact x Confidence / Effort

InputDefinitionScale
ReachUsers or accounts affected per fixed period (e.g. per quarter)Count from analytics, not a guess when data exists
ImpactEffect on the target metric per user reached3 massive, 2 high, 1 medium, 0.5 low, 0.25 minimal
ConfidenceHow well evidence supports reach and impact100% data-backed, 80% some evidence, 50% gut feel; below 50% means research first
EffortTotal person-months (or person-weeks) across all functionsTeam estimate, never yours alone

Fix the time period and effort unit for the whole list before scoring anything.

ICE

score = Impact x Confidence x Ease, each 1-10. Write a one-line anchor for 1, 5 and 10 on each scale before scoring (“Ease 10 = one engineer, under a day”) or scores drift between items and people.

WSJF and cost of delay

  • SAFe-style WSJF: (business value + time criticality + risk reduction / opportunity enablement) / job size, each scored relative to the other items, usually on a Fibonacci-like scale (1, 2, 3, 5, 8, 13, 20). Score one column at a time across all items, with the smallest item set to 1.
  • CD3 (cost of delay divided by duration) when money can be estimated: cost of delay in currency per week, duration in weeks. An item losing 20k/week that takes 2 weeks (10k per week of work) beats one losing 50k/week that takes 10 weeks (5k).
  • Call out urgency profiles: fixed date (regulatory, event), decaying (competitive window), standard, and intangible (platform health). Fixed-date items with real penalties are scheduled, not scored.

Kano

Classify features with the paired question survey: “How would you feel if the product had X?” and “…did not have X?”, each answered Like / Expect / Neutral / Tolerate / Dislike. Map answer pairs to Must-be, Performance, Attractive, Indifferent or Reverse. Need roughly 20-30 respondents per segment for a stable read. Use the result to make sure Must-be gaps are fixed first, then score Performance and Attractive items with RICE. Survey design details: $survey-design.

MoSCoW

For one release with a fixed date. Cap Must at about 60% of the estimated effort so Should and Could absorb overruns. “Won’t (this time)” must be written down and shown to stakeholders.

Workflow

- [ ] 1. Get the list, the goal or metric it should move, and the time horizon
- [ ] 2. Pick the framework (table above); confirm with the user if unclear
- [ ] 3. Fix scales, period and units; write anchors
- [ ] 4. Fill inputs with an evidence note per cell; mark guesses
- [ ] 5. Ask the team for effort/job size; never invent engineering estimates
- [ ] 6. Score with scripts/score_backlog.py
- [ ] 7. Run the sensitivity check; flag ties
- [ ] 8. Write the ranked list with rationale and the decision owner's overrides

Scoring script

scripts/score_backlog.py scores a CSV and prints a ranked table, flags items within 10% of the top score as ties, and validates ranges (RICE impact values, 1-10 ICE scales, positive effort):

python3 scripts/score_backlog.py backlog.csv --method rice --out ranked.csv
python3 scripts/score_backlog.py experiments.csv --method ice
python3 scripts/score_backlog.py epics.csv --method wsjf

Columns: item,reach,impact,confidence,effort (RICE; confidence as 0-1 or percent), item,impact,confidence,ease (ICE), or item,business_value,time_criticality,risk_reduction,job_size (WSJF). Extra columns such as evidence pass through to the output CSV.

Sensitivity check

For each of the top five items, halve its least-certain input (usually reach or confidence) and re-score. If the item drops out of the top five, its rank depends on a guess: label it “rank sensitive - validate X first” and propose the cheapest test ($product-discovery). Items within 10% of each other are ties; break ties on strategy fit or dependencies, and say so.

Output template

## Prioritized backlog - <scope>, <framework>, period <Q>
Goal: <metric this list should move>

| Rank | Item | Score | Key evidence | Sensitive? |
|---|---|---|---|---|
| 1 | Slack invites | 640 | 1,200 workspaces/qtr hit invite step (funnel) | No |

Ties and judgement calls:
- <item A> vs <item B>: tied; chose A because <reason>
Overrides by owner:
- <item> moved from 6 to 2 because <contract / strategic reason>
Needs evidence before scoring:
- <item>: confidence < 50%; run <test>

Gotchas

  • Scores are inputs to a decision, not the decision. Record overrides openly rather than tweaking numbers until the desired order appears.
  • Reach inflation: “all users” is rarely true. Use the users who hit the relevant flow.
  • Effort from product alone is always low. Include design, QA, data, docs and rollout.
  • Re-scoring the same list weekly creates churn. Re-score when evidence changes.
  • Bugs, compliance work and incidents bypass the model; schedule them by severity.
  • Do not compare RICE scores across teams with different reach units.

Verification

Run the script without errors; confirm every cell has an evidence note or a “guess” mark; confirm effort values came from the team; and confirm the top items survive the sensitivity check or are labelled sensitive. Re-read the final list against the stated goal: if the top item would not move that metric, the inputs or the goal are wrong.

What the zip contains

Codex reads bundled files only when a step points to them. Every one is shown here, so you can review it before installing.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Prioritization Frameworks"
  short_description: "RICE, WSJF and Kano scores you can defend"
  default_prompt: "$prioritization-frameworks Score these 25 feature requests with RICE and tell me which rankings are shaky"
scripts/score_backlog.py112 lines, 4.3 KB
#!/usr/bin/env python3
"""Score and rank a backlog CSV with RICE, ICE or WSJF.

Usage:
  python3 score_backlog.py backlog.csv --method rice [--out ranked.csv]

Required columns per method (header names are case-insensitive):
  rice: item, reach, impact, confidence, effort
        impact in {0.25, 0.5, 1, 2, 3}; confidence as 0-1 or 0-100 (%)
  ice:  item, impact, confidence, ease          (each 1-10)
  wsjf: item, business_value, time_criticality, risk_reduction, job_size
        (relative scores, typically Fibonacci 1,2,3,5,8,13,20)

Exits non-zero when columns are missing or values are out of range.
Standard library only.
"""
import argparse
import csv
import sys

METHODS = {
    "rice": ["item", "reach", "impact", "confidence", "effort"],
    "ice": ["item", "impact", "confidence", "ease"],
    "wsjf": ["item", "business_value", "time_criticality", "risk_reduction", "job_size"],
}
RICE_IMPACT = {0.25, 0.5, 1.0, 2.0, 3.0}


def num(row, key, line):
    raw = (row.get(key) or "").strip().rstrip("%")
    try:
        return float(raw)
    except ValueError:
        raise ValueError(f"line {line}: '{key}' is not a number: {row.get(key)!r}")


def score(method, row, line):
    if method == "rice":
        reach, impact = num(row, "reach", line), num(row, "impact", line)
        conf, effort = num(row, "confidence", line), num(row, "effort", line)
        if conf > 1:
            conf /= 100.0
        if impact not in RICE_IMPACT:
            raise ValueError(f"line {line}: impact {impact} not in {sorted(RICE_IMPACT)}")
        if not 0 < conf <= 1:
            raise ValueError(f"line {line}: confidence must be in (0, 1] or (0, 100]")
        if effort <= 0 or reach < 0:
            raise ValueError(f"line {line}: effort must be > 0 and reach >= 0")
        return reach * impact * conf / effort
    if method == "ice":
        vals = [num(row, k, line) for k in ("impact", "confidence", "ease")]
        if any(not 1 <= v <= 10 for v in vals):
            raise ValueError(f"line {line}: ICE values must be 1-10")
        return vals[0] * vals[1] * vals[2]
    bv, tc, rr = (num(row, k, line) for k in ("business_value", "time_criticality", "risk_reduction"))
    size = num(row, "job_size", line)
    if size <= 0:
        raise ValueError(f"line {line}: job_size must be > 0")
    return (bv + tc + rr) / size


def main():
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("csv_path")
    ap.add_argument("--method", choices=sorted(METHODS), required=True)
    ap.add_argument("--out", help="write ranked CSV with score and rank columns")
    args = ap.parse_args()

    with open(args.csv_path, newline="", encoding="utf-8-sig") as fh:
        reader = csv.DictReader(fh)
        if not reader.fieldnames:
            sys.exit("error: empty CSV")
        reader.fieldnames = [f.strip().lower() for f in reader.fieldnames]
        missing = [c for c in METHODS[args.method] if c not in reader.fieldnames]
        if missing:
            sys.exit(f"error: missing columns for {args.method}: {', '.join(missing)}")
        rows, errors = [], []
        for line, row in enumerate(reader, start=2):
            try:
                row["score"] = round(score(args.method, row, line), 2)
                rows.append(row)
            except ValueError as exc:
                errors.append(str(exc))
    if errors:
        print("\n".join(f"error: {e}" for e in errors), file=sys.stderr)
        sys.exit(1)
    if not rows:
        sys.exit("error: no data rows")

    rows.sort(key=lambda r: r["score"], reverse=True)
    for i, r in enumerate(rows, start=1):
        r["rank"] = i
    width = max(len(r["item"]) for r in rows)
    print(f"{'rank':>4}  {'item':<{width}}  score ({args.method})")
    for r in rows:
        print(f"{r['rank']:>4}  {r['item']:<{width}}  {r['score']}")
    top = rows[0]["score"]
    close = [r["item"] for r in rows[1:] if top and abs(top - r["score"]) / top <= 0.10]
    if close:
        print(f"\nnote: within 10% of the top score: {', '.join(close)} - treat as a tie and decide on judgement")

    if args.out:
        fields = list(rows[0].keys())
        with open(args.out, "w", newline="", encoding="utf-8") as fh:
            w = csv.DictWriter(fh, fieldnames=fields)
            w.writeheader()
            w.writerows(rows)
        print(f"\nwrote {args.out}")


if __name__ == "__main__":
    main()

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc
Just launched

Codex Skills Pro is live

79 premium skills for Codex, each with scripts, references and an evidence report that proves the result.

Bought one by one$882.21
All 79 skills$49
94% off

That's $0.62 a skill, paid once.

Get all 79 for $49Or pick single skills from $4.99 →

Secure checkout by Creem