pan-open-threads · git:20260920.d35b93e · 2026-09-20 · sha256 626c3a5978441527

pan-open-threads git:20260920.d35b93eB

Immutable. This exact content never changes and is served at /api/v1/blob/626c3a5978441527.

---
name: pan-open-threads
description: >
  Build an "open threads ledger": read every active Overdeck conversation, list
  every topic the operator raised that is still unfinished (what they owe, what
  is at risk, questions agents asked and never got answered, work nobody is
  driving), and publish it as a checkable Claude Code artifact page that
  persists ticks. Re-runs update the same page. Use when the operator says
  they have lost track of what they were juggling, asks "what did I leave
  hanging", "what's still open across my conversations", "where did I leave
  that", or wants the ledger refreshed. Not for pipeline status (use
  pipeline-status) or a daily recap (use pan-recap).
triggers:
  - /pan-open-threads
  - open threads
  - what was I juggling
  - what did I leave hanging
  - where did I leave that
  - what's still open across my conversations
  - refresh the ledger
  - open threads ledger
allowed-tools:
  - Bash
  - Read
  - Write
  - Agent
  - Artifact
---

# pan-open-threads — the open threads ledger

The operator runs many conversations at once and loses track of the small
asks, decisions, and questions inside each one. This skill reads every active
conversation, extracts the unfinished threads, and publishes them as one
checkable page. It is thread-level (what the operator said), not issue-level.

## Output

A Claude Code artifact page titled **Open Threads Ledger**, built from
`{baseDir}/assets/ledger-template.html`. One block per conversation, one
checkbox per open item, each item tagged:

| Tag | Meaning |
| --- | --- |
| `owe` | only the operator can do it (a click, a decision, a message they never finished) |
| `risk` | data or money is exposed (unpushed commits, secrets on disk, a wrong key) |
| `ask` | an agent asked the operator something and never got an answer |
| `open` | pending work nobody is driving |

A separate **Safe to close** section lists conversations that are finished or
empty. Ticks persist through the `artifact` capability (the page republishes
itself), with localStorage as the per-viewer fallback.

## Procedure

### 1. Enumerate active conversations

```bash
curl -s http://localhost:3011/api/conversations | python3 -c "
import sys,json; d=json.load(sys.stdin)
for c in d:
    if c.get('status')=='active': print(c['id'], c.get('harness'), c.get('projectKey'), c.get('lastActivityAt'), '|', c.get('title'))"
```

Skip conversations whose title is "New conversation" and whose transcript is
empty; list them under Safe to close as empty shells.

### 2. Dump each transcript

```bash
python3 {baseDir}/scripts/dump_conv.py <conv-id> > /path/to/scratch/conv-<id>.txt
```

The script handles claude-code JSONL (via `pan conversations jsonl`), Codex
rollouts under `~/.overdeck/agents/conv-<name>/codex-home/`, and OpenCode
sessions in `~/.local/share/opencode/opencode.db`. Output is `>>> USER [ts]`
and `--- ASST [ts]` blocks. Two traps:

- **Codex dumps are inflated.** Most `>>> USER` blocks are the harness's own
  approval-assessor prompts ("The following is the Codex agent history whose
  request action you are assessing"). Readers must count only real operator
  messages and use the approval blocks only as evidence of what ran.
- **Assistant blocks are truncated** (1500 chars by default). Where a reply is
  cut off, say so rather than guessing the conclusion.

### 3. Fan out readers

Spawn one `general-purpose` Agent per large conversation and group the small
ones (under ~30 KB) into one reader. Give each reader the dump path and this
contract:

> One entry per distinct topic the OPERATOR raised, chronological. Include
> side questions and small asks; merge repeated nudges on one topic. Per
> entry: topic in plain words, what the operator asked or decided, what the
> assistant did or concluded, STATUS (DONE / OPEN / WAITING ON OPERATOR /
> HANDED OFF to a named target), and any issue IDs, PRs, commits, paths.
> Then a DANGLING list: every ask with no completion evidence, every
> question the assistant asked that was never answered, and the last thing
> that happened with a verdict of settled or mid-task.

Ask readers to run read-only live checks (`gh issue view`, `pan show`) when a
transcript claims something was filed or landed, and to withhold secrets a
transcript may contain (API keys, passwords).

### 4. Compile

Keep only items that are still open. For each conversation write one line on
where it stopped, then the items with tags. Put loss risks (unpushed commits,
a possibly-submitted key reset, untracked PRDs) and mid-sentence operator
messages ("And also…") where they will be seen. Consolidate unanswered
agent questions into the `ask` tag rather than a separate list. Decide Safe
to close: finished, empty, or handed off to a successor conversation.

Save the compiled inventory to a scratch file before publishing so it
survives the session.

### 5. Publish

Copy `{baseDir}/assets/ledger-template.html` to the scratchpad, replace the
`GROUPS` array and the `CLOSEABLE` list with the compiled data, update the
stamp line, and publish:

```
Artifact file_path=<copy> favicon=🧵 capabilities={"artifact": {}}
       description="Every unfinished thread across your open Overdeck conversations, with checkboxes that save for everyone."
```

**Re-runs update the same page.** Find it with `Artifact action=list`,
`action=read` it, carry forward the ticked ids from its
`<script id="ledger-state">` block (item ids are `<conv>-<index>`, so keep
item order stable within a conversation when only appending), and publish
with `url=<existing>`. Never create a second ledger.

## Style rules for the page and the reply

- Link every issue ID on every occurrence (see the issue-references rule) and
  every conversation number as `https://overdeck.localhost/conv/<id>`.
- Plain language: name what a thread is, never a bare ID.
- Timestamps in UTC.
- In the terminal reply, lead with whichever thread the operator named, then
  the page link, then the loss risks. Do not reprint the whole ledger.