deft-directive-portfolio-priority · git:20260902.f81e154 · 2026-09-02 · sha256 eac61bdd836be091
deft-directive-portfolio-priority git:20260902.f81e154A
Immutable. This exact content never changes and is served at /api/v1/blob/eac61bdd836be091.
---
name: deft-directive-portfolio-priority
description: >-
Pre-promotion portfolio prioritization: cluster competing open RFCs/issues
from the local github-issue cache, emit a propose-not-apply priority brief
(conflict matrix, shortlist, park), with epistemic citation gates, then hand
off for operator dispose. Use when the operator asks for portfolio priority,
a priority brief, competing RFCs, or to cluster open issues. Do NOT trigger
on single-item "what's next?" ranking (deft-directive-triage / triage:queue)
or post-promotion capacity prioritization (#1419/#1511).
triggers:
- portfolio priority
- priority brief
- competing RFCs
- cluster open issues
- pre-promotion portfolio
- portfolio prioritization
- rank this backlog slice
metadata:
clawdbot:
requires:
bins: ["gh"]
---
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
<!-- Purpose: rendered skill -->
<!-- Source of truth: packs/skills/skills-pack-0.1.json -->
<!-- Regenerate with: task packs:render -->
<!-- Edit the source, not this file. Slice instead of loading every SKILL.md: task packs:slice skills by-trigger --trigger <kw> (or list) -->
# Deft Directive Portfolio Priority
Pre-promotion **portfolio prioritization pass**: cluster competing RFCs/issues from the local github-issue cache, name conflicts/supersession, emit a **propose-not-apply** priority brief (shortlist + park), then hand off for operator dispose. Parent process + dogfood: **#3198**. Worked example: **#3200** / [`docs/analysis/2026-08-07-portfolio-priority-brief-patterns-pilot.md`](../../../docs/analysis/2026-08-07-portfolio-priority-brief-patterns-pilot.md).
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
## When to Use
- Maintainer wants a **portfolio priority** brief across competing open issues / RFCs
- Operator says: portfolio priority, priority brief, competing RFCs, cluster open issues, pre-promotion portfolio, rank this backlog slice
- After a large classify / label-mirror partition when humans still need a shortlist (B-side; not the ranker)
- ⊗ Do NOT use for single-issue "what's next?" ranking — that is `deft-directive-triage` + `task triage:queue`
- ⊗ Do NOT use for post-promotion capacity buckets — that is #1419 / #1511
- ⊗ Do NOT use for review-handoff briefs — that is #1590
## Stance (hard)
- ! **Propose-not-apply** (#3179): the brief proposes; the operator disposes
- ⊗ SCM label writes, mirror `--apply`, or re-enrich apply from this skill
- ⊗ `task triage:accept` / reject / defer / needs-ac / mark-duplicate / bulk-*
- ⊗ Scope lifecycle (`scope:promote` / `activate` / `complete` / `cancel`) from this skill
- ⊗ Treat the brief as a decision record — dispose via `task decision:write` / plan-sequence / operator comment (#1396)
## Inputs
- ! Local `.deft-cache/github-issue/` (bodies available)
- ! Classify --mirror is withdrawn (#4070). Use a read-only `task triage:queue` listing (or a captured #4070 digest) as **FILTER only**. ⊗ Run `task triage:classify -- --mirror`.
- ~ Optional theme slice: label family, title prefix, author, epic parent
## Phases
### Phase 0 — Cache freshness
1. ! Run `task verify:cache-fresh`. Exit 0 → proceed. Exit 1 → refresh (`task cache:fetch-all -- --source=github-issue --repo OWNER/NAME`) or **disclose stale** and continue only with operator consent. Exit 2 → `task triage:bootstrap` first.
2. ~ When zero cache entries, bootstrap/fetch before clustering (#2575).
3. ⊗ Cluster against a silent stale cache without disclosing staleness.
### Phase 1 — Classify as FILTER only
1. ! Classify --mirror is withdrawn (#4070). Partition from a read-only `task triage:queue` listing or a captured digest from `task triage:strip-withdrawn-chips -- --emit-digest`. ⊗ Run live `task triage:classify -- --mirror`.
2. ! Use classify outcomes only to **filter** the portfolio slice (e.g. deep-dive candidates from `no_match`; keep escalate on an interrupt queue).
3. ⊗ Use classify disposition chips as the **ranker** or final shortlist order.
4. ⊗ Pass `--apply` or `--re-enrich` with intent to write labels from this skill.
### Phase 2 — Theme / slice selection
1. ! Name an **explicit slice** (label family, title theme, author, or epic). Unattended full-backlog ranking is out of scope.
2. ! Record scope counts: open in slice, classify partitions inside the slice, exclusions.
3. ~ Prefer one coherent theme per brief (pilot: patterns + `no_match`).
### Phase 3 — Cluster + conflict matrix + shortlist + park
1. ! Group candidates into **families** (title/theme/body overlap, shared parent epic, layered pack).
2. ! Build a **conflict / supersession matrix** per family: overlapping roots, pack-vs-atom, research-vs-product.
3. ! Emit an ordered **shortlist** (deep dive / promote candidates) and a **park list** with park reasons.
4. ! Separate **interrupt / non-portfolio** rows (escalate, hold, already dispositioned) so they are not ranked against park list.
5. ⊗ Claim "#X supersedes #Y" from titles alone — see Phase 4 epistemic gates.
6. ! **List-before-re-recommend** (#3315): for each cited `#N` before re-recommending an overlap, run `task decision:list -- --issue N --json` and match `relatedIssues` from the JSON. Park / do not re-shortlist as novel overlap only when a dispose decision's `relatedIssues` covers this overlap's members (not some other relationship that merely mentions N), unless `revisitTrigger` applies. Advisory diligence — not a `task check` gate. ⊗ Auto-close issues or treat the brief as the dispose record.
7. Parent/child, leaf/tracker, and sibling-validator pairs are **not** duplicates — #3066/#3082, #95/#96, #513/#514.
### Phase 4 — Epistemic gates (MUST)
Before citing any `#N` in the brief:
1. ! **Verify existence + state** for every cited issue via live `gh api repos/OWNER/NAME/issues/N` (REST) **or** a proven-fresh cache entry whose state matches the claim.
2. ! **Read the body** of every issue used for shortlist, park-as-superseded, duplicate/consolidate classification, pack membership, or "decided" claims.
3. ! When claiming decided / superseded / closed-by-comment, also **read comments** (REST `issues/N/comments`).
4. ! State **open/closed accurately**; never invent issue numbers.
5. ⊗ **Title-only supersession**, duplicate, or ownership claims.
6. ⊗ Cite PRs as issues without filtering `pull_request` on mixed issue lists.
### Phase 5 — Emit priority brief
! Write markdown matching the pilot section shape (fill with this run's slice):
1. **Header** — process issue (#3198 or project equivalent), parent tracker if any, generated timestamp, stance (propose-not-apply), epistemic method
2. **Dispose path** — not a decision record; points at #1396 / plan-sequence / operator comment
3. **Scope of this pass** — counts table (slice filters + partition sizes)
4. **Interrupt / non-portfolio** — escalate/hold/already planned (do not rank here)
5. **Conflict / family matrix** — families with verified state + body claims + recommendation
6. **Shortlist** — ordered P1/P2/… with why
7. **Park list** — classes, examples, park reasons
8. **Epistemic limits** — what was cache-only, what needs follow-up probe
9. **Operator dispose checklist** — accept/edit shortlist, accept park, record dispose, optional plan-sequence; do not treat as mirror apply
~ Prefer writing under `docs/analysis/YYYY-MM-DD-portfolio-priority-brief-<slice>.md` for durable dogfood; chat-only is allowed if the operator declines a file.
~ Link the worked example: #3200 and `docs/analysis/2026-08-07-portfolio-priority-brief-patterns-pilot.md` (may live on the pilot PR until merged).
### Phase 6 — Dispose checklist (hand off)
1. ! Present the dispose checklist to the operator (accept/edit shortlist + park; record dispose; optional plan-sequence for P1).
2. ! Point dispose targets: `task decision:write` (#1396 / [`docs/decision-log.md`](../../docs/decision-log.md)): every overlap-cluster member in `relatedIssues`; include `revisitTrigger`; free-text MAY name relationship. Optional `task plan-sequence:set`. Interim issue comment only if the write surface is unavailable.
3. ⊗ Auto-promote shortlist into plan-sequence without explicit operator dispose.
4. ⊗ Exit treating the brief alone as durable prioritization memory (#2741 class).
~ Dedicated duplicate-clusters ledger is deferred; earn it only when a pass re-litigates a cluster despite a dispose decision listing the members (#3310). Boundaries: #886, #1178, #786, #3198/#3201, #1396.
## Anti-Patterns
- ⊗ SCM label writes / mirror apply / re-enrich apply from this skill
- ⊗ `triage:accept` or any triage decision verb from this skill
- ⊗ Scope lifecycle mutations from this skill
- ⊗ Title-only supersession or unverified `#N` citations
- ⊗ Full open-backlog unattended ranking without an explicit slice
- ⊗ Replacing `triage:queue` for buildable work selection
- ⊗ Treating the brief as the decision record without dispose
- ⊗ Re-shortlist a disposed overlap without `task decision:list -- --issue N` (#3315)
## EXIT
! Confirm: `deft-directive-portfolio-priority complete -- exiting skill.`
~ Chain: operator dispose (`task decision:write` / plan-sequence) · `deft-directive-triage` for single-item queue work · `deft-directive-refinement` after accept on a different path · do **not** chain into mirror apply.
⊗ Silent exit.
## References
- #3198 process + dogfood · #3201 this skill · #3200 / patterns pilot brief
- #1396 decision log · #3179 propose-not-apply · #1423 / #3197 classify filter only
- #3315 overlap dispose · #3310 ledger archive · #886 / #1178 / #786 boundaries
- Siblings: `deft-directive-triage`, `deft-directive-refinement` — not #1419/#1511 post-promotion