Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 33 additions & 43 deletions .claude/hooks/issues-surface.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# SessionStart hook — surface the outstanding-work memory into context.
#
# Reads docs/outstanding-issues.md (the /issues ledger) and prints a compact,
# glanceable summary of the OPEN items so every session starts already aware of
# what is outstanding. When the trigger is a context reset (compact / resume /
# clear) it also emits a reminder to run `/issues capture` — that is the moment
# glanceable summary of the RECOMMENDED EXECUTION QUEUE so every session starts
# aware of the ordered work still worth doing. When the trigger is a context reset
# (compact / resume / clear), it also emits a reminder to run `/issues capture` — that is the moment
# a session's in-flight follow-ups are most likely to be lost.
#
# Contract: READ-ONLY. Never writes, never commits, never fails a session — it
Expand All @@ -25,59 +25,49 @@ source_val="$(printf '%s' "$payload" \
| grep -o '"source"[[:space:]]*:[[:space:]]*"[^"]*"' \
| head -n1 | sed -E 's/.*"([^"]*)"$/\1/')"

# --- parse the "Open items" table only ---------------------------------------
# Emit "PRI<TAB>ID<TAB>TYPE<TAB>SUMMARY" per open row. Scoped between the
# "## Open items" heading and the next "## " heading so the Resolved/archive
# table (different columns) is never counted.
# --- parse the "Recommended execution queue" table only ---------------------
# Emit "ORDER<TAB>ACUITY<TAB>SOURCE<TAB>OUTCOME<TAB>CLASSIFICATION" per row.
rows="$(awk '
/^## Open items/ { inopen=1; next }
/^## / { if (inopen) inopen=0 }
inopen && /^\| #[0-9]/ {
/^## Recommended execution queue/ { inqueue=1; next }
/^## / { if (inqueue) inqueue=0 }
inqueue && /^\|[[:space:]]*[0-9]+[[:space:]]*\|/ {
n=split($0, c, "|")
id=c[2]; pri=c[3]; typ=c[4]; sum=c[5]
gsub(/^[ \t]+|[ \t]+$/, "", id)
gsub(/^[ \t]+|[ \t]+$/, "", pri)
gsub(/^[ \t]+|[ \t]+$/, "", typ)
gsub(/^[ \t]+|[ \t]+$/, "", sum)
printf "%s\t%s\t%s\t%s\n", pri, id, typ, sum
ord=c[2]; src=c[3]; out=c[4]; acu=c[5]; cls=c[6]
gsub(/^[ \t]+|[ \t]+$/, "", ord)
gsub(/^[ \t]+|[ \t]+$/, "", src)
gsub(/^[ \t]+|[ \t]+$/, "", out)
gsub(/^[ \t]+|[ \t]+$/, "", acu)
gsub(/^[ \t]+|[ \t]+$/, "", cls)
printf "%s\t%s\t%s\t%s\t%s\n", ord, acu, src, out, cls
}
' "$ledger" 2>/dev/null || true)"

total="$(printf '%s' "$rows" | grep -c . || true)"
if [ "${total:-0}" -eq 0 ]; then
echo "[issues] Outstanding-work memory (docs/outstanding-issues.md): no open items. Record one with /issues add …"
echo "[issues] Universal task ledger (docs/outstanding-issues.md): no recommended work."
exit 0
fi

group() { printf '%s\n' "$rows" | awk -F'\t' -v p="$1" '$1==p'; }
count() { printf '%s' "$1" | grep -c . || true; }
p1="$(group P1)"; p2="$(group P2)"; p3="$(group P3)"
c1="$(count "$p1")"; c2="$(count "$p2")"; c3="$(count "$p3")"
c1="$(printf '%s\n' "$rows" | awk -F'\t' '$2=="P1" { count++ } END { print count+0 }')"
c2="$(printf '%s\n' "$rows" | awk -F'\t' '$2=="P2" { count++ } END { print count+0 }')"
c3="$(printf '%s\n' "$rows" | awk -F'\t' '$2=="P3" { count++ } END { print count+0 }')"

echo "[issues] Outstanding-work memory — ${total} open (${c1}×P1, ${c2}×P2, ${c3}×P3). Source of truth: docs/outstanding-issues.md · read the full list back with /issues."
echo "[issues] Universal task ledger — ${total} recommended (${c1}×P1, ${c2}×P2, ${c3}×P3). Source of truth: docs/outstanding-issues.md · read the full queue with /issues."

print_group() { # $1=rows $2=max-to-list
local data="$1" limit="$2" shown=0 more=0 pri id typ sum
[ -z "$data" ] && return 0
while IFS=$'\t' read -r pri id typ sum; do
[ -z "$pri" ] && continue
if [ "$shown" -lt "$limit" ]; then
echo " ${pri} ${id} ${typ} — ${sum}"
shown=$((shown + 1))
else
more=$((more + 1))
fi
done <<EOF
$data
shown=0
more=0
while IFS=$'\t' read -r ord acu src out cls; do
[ -z "$ord" ] && continue
if [ "$shown" -lt 10 ]; then
echo " ${ord}. ${acu} ${src} — ${out} (${cls})"
shown=$((shown + 1))
else
more=$((more + 1))
fi
done <<EOF
$rows
EOF
[ "$more" -gt 0 ] && echo " … +${more} more at this priority (see /issues)"
return 0
}

# P1 = do-next, list all. P2 = should-do, list up to 8. P3 = collapse to a count.
Comment thread
BigSimmo marked this conversation as resolved.
[ "$c1" -gt 0 ] && print_group "$p1" 999
[ "$c2" -gt 0 ] && print_group "$p2" 8
[ "$c3" -gt 0 ] && echo " ${c3} × P3 (nice-to-have / revisit-when) — see /issues"
[ "$more" -gt 0 ] && echo " … +${more} more in queue order (see /issues)"

# --- capture reminder ---------------------------------------------------------
case "$source_val" in
Expand Down
59 changes: 32 additions & 27 deletions .claude/skills/issues/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
---
name: issues
description: Track and recall all outstanding tasks, recommendations, and issues for this repo as durable cross-session memory. Use when the user types "/issues" (state the open items back), or asks to add/close/update/capture an outstanding task, recommendation, or issue. The memory lives in docs/outstanding-issues.md; a plain "/issues" is read-only.
description: Maintain and recall the repository's single universal recommended task ledger. Use when the user types "/issues" (state the recommended execution queue back), or asks to add, close, update, or capture work. The memory lives in docs/outstanding-issues.md; a plain "/issues" is read-only.
---

# issues — the outstanding-work memory
# issues — universal task-ledger memory

`docs/outstanding-issues.md` is the durable, cross-session memory of everything still outstanding:
open **tasks**, **recommendations** not yet acted on, and **issues** not yet resolved. Chat context
resets; that file does not. This skill reads it back and keeps it current.
`docs/outstanding-issues.md` is the durable, cross-session memory and single universal task ledger.
Its **Recommended execution queue** is the only active repository-wide work order. The Open and
Resolved tables retain source detail and audit history; an open row is not active work unless it is
also represented in the recommended queue.

**The ledger is the source of truth, not chat memory.** Never answer `/issues` from conversation
recall — always read the file first, so the answer is correct even in a fresh session.
Expand All @@ -20,53 +21,57 @@ recall — always read the file first, so the answer is correct even in a fresh
## Default: `/issues` (read-only)

1. Read `docs/outstanding-issues.md`.
2. State the **open items** back, grouped by priority (P1 → P3), each as
`#ID · type · summary — next action (source)`.
3. End with a one-line count, e.g. `5 open: 0×P1, 3×P2, 2×P3 · 0 resolved this session`.
2. State the **Recommended execution queue** back in numeric order, each as
`order · source · acuity · outcome — classification; when; estimate`.
3. End with a one-line count by acuity, e.g. `5 recommended: 0×P1, 3×P2, 2×P3`.
4. Do **not** mutate the file or commit on a plain read.

If a filter is given, narrow step 2: `/issues P1` (by priority), `/issues issues` / `/issues recs`
/ `/issues tasks` (by type), `/issues <keyword>` (summary/detail substring match).
If a filter is given, narrow step 2 by acuity, source ID, classification, intelligence, timing, or
outcome keyword. Read the matching source row when more detail is requested.

## Mutating subcommands

Parse the intent from natural language too — the exact syntax is a convenience, not a requirement.

- **`/issues add <text>`** — append a row to **Open items**. Infer `Pri`/`Type` from the text
(ask only if genuinely ambiguous; default `P2`/`task`). Allocate the ID from the
`<!-- issues:next-id=NNN -->` marker, then bump that marker. Fill `Source` with
`session <today>` unless the user names one; `Added` is today's date.
- **`/issues add <text>`** — verify that the work is current, deduplicated, evidence-supported, and
still recommended. Then append a detailed source row to **Open items**, add its concise ordered row
to the **Recommended execution queue**, and bump `<!-- issues:next-id=NNN -->`. Capture outcome,
acuity, classification, intelligence, timing, estimate, dependencies/approvals, success criteria,
verification, and stopping condition. Ask when a high-impact field cannot safely be inferred.
- **`/issues done <id> [outcome]`** — move that row from **Open items** to **Resolved / archive**
with today's date and a one-line outcome. Archive, never delete.
- **`/issues update <id> <text>`** — edit an open row's summary or next action in place.
with today's date and a one-line outcome, remove that ID from the recommended queue, and renumber
queue order contiguously. For a grouped queue row, remove only that ID unless none remain.
- **`/issues update <id> <text>`** — edit the source row and synchronize every affected queue field.
- **`/issues capture`** — scan the current session for recommendations, follow-ups, deferrals, and
unfixed problems that surfaced but were not recorded. Propose them as a numbered list and add the
confirmed ones (dedupe against existing rows first — do not re-add something already tracked).
unfixed problems. Verify them against current repository evidence, remove completed/stale/
duplicate/superseded/speculative/uneconomic candidates, and propose only work still recommended.
Add confirmed items to both active and source tables.

## Capture discipline (proactive memory)

When a task in _any_ session ends with unresolved follow-ups — a deferred fix, a "revisit when X"
recommendation, a known risk, a TODO you had to leave — offer to record them here before the context
is lost. That is what makes this a memory rather than a static list. Prefer one crisp row over a
paragraph; put the smallest next action in **Detail / next action**.
When a task ends with a verified follow-up worth doing, offer to record it before context is lost.
Do not capture every suggestion or TODO. Prefer one crisp source row and one ordered queue row over a
paragraph, and state the smallest next action and stop condition.

## Writing rules

- Keep the table format and column order exactly as in `docs/outstanding-issues.md`. One row per item.
- IDs are monotonic and never reused — always allocate from the `issues:next-id` marker and bump it.
- Queue order is contiguous and dependency-aware. Re-evaluate affected rows after each mutation.
- Keep nonrecommended/refuted/parked claims out of the queue; retain them below only as audit history.
- Escape `|` inside cell text (write `\|`) so the markdown table stays intact.
- Respect the repo's RAG/clinical/privacy flagging rules if an item _itself_ touches a protected
surface — recording it here is fine, but acting on it later still needs the usual gate.

## Persist the memory (commit)
## Persist the memory

After any mutation, stage and commit **only** `docs/outstanding-issues.md` so the memory survives the
ephemeral container and other worktrees:
When the user authorizes a commit or the mutation is already inside an authorized handoff, stage and
commit **only** `docs/outstanding-issues.md` so the memory survives other worktrees:

```
git add docs/outstanding-issues.md
git commit -m "issues: <what changed>"
```

Do not stage or commit anything else, and do not push unless the user asks (or you are already in a
handoff/upload flow). A plain read-only `/issues` commits nothing.
Otherwise leave the mutation uncommitted and report that state. Do not push unless the user asks (or
you are already in an authorized handoff/upload flow). A plain read-only `/issues` commits nothing.
24 changes: 14 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -450,19 +450,23 @@ Run the matching planner command in `docs/productivity-workflows.md` without sid

## Outstanding-work memory (`/issues`)

`docs/outstanding-issues.md` is the durable, cross-session memory of every outstanding **task**,
**recommendation**, and **issue** for this repo. Chat context resets between sessions; that file does
not, so anything worth remembering after a session ends belongs there.
`docs/outstanding-issues.md` is this repository's single universal task ledger. Its recommended
execution queue keeps only evidence-supported work still worth doing and records order, acuity,
classification, executor capability, timing, effort, dependencies, approvals, success criteria,
verification, and stopping conditions. Completed, stale, duplicate, superseded, speculative, and
no-longer-recommended claims may remain only in archive/history, never as active work. Do not create
a second task ledger.

- When the user types `/issues`, invoke the `issues` skill (`.claude/skills/issues/SKILL.md`): read
`docs/outstanding-issues.md` and state the open items back, grouped by priority. A plain `/issues`
is read-only — it mutates and commits nothing.
- `/issues add|done|update|capture …` mutate the ledger; each mutation commits **only**
`docs/outstanding-issues.md` (no push unless the user asks or you are already handing off).
- Proactively offer to `capture` unresolved follow-ups, deferrals, and known risks into the ledger
before a session's context is lost — that is what keeps it a memory rather than a stale list.
`docs/outstanding-issues.md` and state its recommended queue back in execution order. A plain
`/issues` is read-only — it mutates and commits nothing.
- `/issues add|done|update|capture …` mutate the ledger only when requested and must keep the
recommended queue and source/archive rows synchronized. Committing, pushing, and opening a PR are
separate Git actions requiring the usual authorization.
- Before capture, verify and deduplicate each candidate. Add only work that remains recommended;
archive or omit completed, stale, duplicate, superseded, speculative, or uneconomic suggestions.
- A `SessionStart` hook (`.claude/hooks/issues-surface.sh`, wired in `.claude/settings.json`)
auto-surfaces the open items into context at the start of every session and, on a context reset
auto-surfaces the recommended queue into context at the start of every session and, on a context reset
(`compact`/`resume`/`clear`), nudges a `/issues capture`. It is read-only — it never writes the
ledger. `/issues` is still the way to read the full list or mutate it.

Expand Down
5 changes: 3 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ npm run docs:check-links

## Plans and workstreams (living)

- [maturity-backlog-workorders.md](maturity-backlog-workorders.md) — actionable work orders tracking the repository-maturity audit backlog
- [outstanding-issues.md](outstanding-issues.md) — the single universal task ledger; its recommended queue is the only active repository-wide work order
- [maturity-backlog-workorders.md](maturity-backlog-workorders.md) — historical maturity work-order evidence; not an independent active queue
- [framework-dependency-modernization-checklist.md](framework-dependency-modernization-checklist.md) — ordered Next.js 16, runtime, dependency, Turbopack, and verification migration program
- [search-rag-master-plan.md](search-rag-master-plan.md) / [search-rag-master-context.md](search-rag-master-context.md) — search/RAG roadmap and shared context
- [rag-hybrid-findings-and-todo.md](rag-hybrid-findings-and-todo.md) — hybrid retrieval findings backlog
- [rag-hybrid-findings-and-todo.md](rag-hybrid-findings-and-todo.md) — hybrid retrieval findings and historical evidence; active work is promoted to the universal ledger
- [reindex-shadow-harness-design.md](reindex-shadow-harness-design.md) — designed-only shadow reindex harness (driver not built)
- [ingestion-concurrency-fix-workorder.md](ingestion-concurrency-fix-workorder.md) — ingestion concurrency workorder
- [redesign/](redesign/) — premium redesign plans, decision log, token adoption
Expand Down
Loading