deftai

deft-directive-portfolio-priority

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).

deftai 31 14 Updated 5d ago
GitHub

Install

npx skillscat add deftai/directive/deft-directive-portfolio-priority

Install via the SkillsCat registry.

SKILL.md

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`.

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`): 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

Categories