Просмотр исходного кода

diagnosing-superpowers: discover session formats from evidence

Drew Ritter 3 недель назад
Родитель
Сommit
bc256ce422

+ 3 - 5
skills/diagnosing-superpowers/SKILL.md

@@ -27,11 +27,9 @@ Create a todo per step. Steps 5–7 run only on their stated condition.
    too long" is a complaint, not a problem statement. Note whether the
    goal is a superpowers bug report.
 2. **Locate.** Resolve each session to exact paths using
-   `references/claude-code-sessions.md`, `references/codex-sessions.md`,
-   or `references/other-harnesses.md` for any other harness. Confirm a
-   past session by quoting its first prompt and timestamp, and list every
-   candidate you rejected with the reason, or "none". Enumerate subagent
-   transcripts. Create
+   `references/session-discovery.md`. Confirm a past session by quoting its
+   first prompt and timestamp, and list every candidate you rejected with the
+   reason, or "none". Enumerate subagent transcripts. Create
    `~/.superpowers/diagnosing-superpowers/<session-id>/`, tell your
    partner the path, and fill `templates/case.md` there, including the
    superpowers install root, version, git sha, and a sha1 for every skill

+ 9 - 9
skills/diagnosing-superpowers/prompts/analyst-common.md

@@ -5,19 +5,20 @@ superpowers should change.
 
 Inputs (from your dispatcher):
 - CASE: absolute path of the case file. Read it first. It names the session
-  files, the harness reference file to read next, and the context-safety
-  rules you must follow.
+  files, the discovered sources and record meanings to use, and the
+  context-safety rules you must follow. Use the recorded meanings rather than
+  repeating discovery or assuming a harness format.
 - RANGE (optional): a turn range or line range. If present, analyze only
   that range and say so in your Checked line.
 
 Context safety: follow `references/context-safety.md`, named in CASE, on
-every file before reading it, and extract fields with the commands in the
-harness reference. "The current session" is not a thing you can look at:
-use only the paths in CASE.
+every file before reading it, and extract fields with the recorded commands or
+queries. "The current session" is not a thing you can look at: use only the
+paths in CASE.
 
-Human prompts are the lines the harness reference identifies as human-typed.
-Hook output, system reminders, and tool results are not human prompts. In a
-subagent transcript, "user" is the parent agent.
+Human prompts are the records the case file identifies as human-typed. Hook
+output, system reminders, and tool results are not human prompts. In a subagent
+transcript, "user" is the parent agent.
 
 Return format (nothing else):
 
@@ -35,4 +36,3 @@ Checked: <what you examined: files, line ranges, commands used>
 The dispatcher discards any finding without a `path:line`, so do not
 write one. If you found nothing, return `- none found` and the Checked
 line.
-

+ 18 - 19
skills/diagnosing-superpowers/prompts/cost-and-time.md

@@ -5,25 +5,24 @@ Dimension: Cost and time
 
 Account for where tokens and wall-clock went.
 
-1. Tokens. Claude Code: sum `message.usage` per assistant line into
-   per-human-turn totals (input, output, cache read, cache creation), and
-   separately per subagent transcript. Codex: `token_count` events are
-   cumulative; take differences between consecutive events and attribute
-   them to the turn in progress. Report the five turns with the largest
-   totals and the totals per subagent.
-2. Wall-clock. Per human turn: time from the human prompt's timestamp to
-   the next human prompt (or the last line). Codex also has
-   `task_complete.duration_ms`. Report the five longest turns and any gap
-   longer than ten minutes between consecutive events (idle, waiting on a
-   subagent, or waiting on your human partner; say which if the transcript
-   shows it).
-3. Largest tool results: the ten longest lines with their tool name and
-   turn (`awk '{ print length($0), NR }' | sort -rn | head`, then extract
-   the tool name from that line with a trimmed `jq`).
-4. Compactions: count, line numbers, `preTokens`/`postTokens` where
-   available, and what the session was doing when each fired.
-5. Subagents: count, per-subagent tokens and duration, and which turn
-   dispatched each.
+1. Tokens. Use only the usage records and counter meanings established in the
+   case file. State whether each counter is incremental or cumulative before
+   calculating totals; difference cumulative observations without turning a
+   missing observation into zero. Report the five turns with the largest
+   supported totals and the supported totals per associated session.
+2. Wall-clock. Use the evidenced timestamp fields, event boundaries, and units
+   recorded in the case file. Report the five longest supported turns and any
+   gap longer than ten minutes between consecutive events (idle, waiting on an
+   associated session, or waiting on your human partner; say which only when
+   the records show it).
+3. Largest tool results: use the case file's evidenced tool-result records to
+   report the ten largest results with their tool and turn. Measure records
+   before extracting bounded content.
+4. Compactions: count and locate records whose meaning as compaction events was
+   established during discovery. Report available before/after counters and
+   what the session was doing when each fired; mark unsupported fields absent.
+5. Associated sessions: count them and report supported usage, duration, and
+   dispatching turn for each.
 6. Report the turns, subagents, tools, or repeats that dominate the
    totals, with numbers. Do not speculate about why a
    turn was expensive beyond what the transcript shows.

+ 6 - 7
skills/diagnosing-superpowers/prompts/plan-adherence.md

@@ -9,14 +9,13 @@ happened. "Plan" here means any agreed course of action, not git commits.
 1. Find the agreed plan: a design or plan agreed in chat (look for the
    assistant text preceding a human "yes/ok/go ahead"), a spec or plan file
    written during the session (tool calls that write under `docs/`,
-   `plans/`, `specs/`, or any file the human named), a todo list
-   (Claude Code `TodoWrite` tool_use inputs; Codex `update_plan` calls;
-   any numbered checklist in assistant text). Quote each plan step with
-   its `path:line`.
+   `plans/`, `specs/`, or any file the human named), a todo-list record whose
+   meaning was established in the case file, or any numbered checklist in
+   assistant text. Quote each plan step with its `path:line`.
 2. Mark structural events between the plan and its execution: compaction
-   (Claude Code `compact_boundary`; Codex `compacted` / `context_compacted`),
-   resumes, aborted turns, and subagent dispatches. Note their line
-   numbers; plan drift right after one of these is a distinct finding.
+   events identified during discovery, resumes, aborted turns, and associated
+   session dispatches. Note their line numbers; plan drift right after one of
+   these is a distinct finding.
 3. For each plan step, find the tool calls and assistant text that
    executed it, or establish that none did. Report:
    - steps skipped (no execution found; quote the plan step);

+ 4 - 3
skills/diagnosing-superpowers/prompts/similar-session.md

@@ -3,7 +3,8 @@ behavior as a diagnosed session. You do not modify any file.
 
 Inputs:
 - CASE: absolute path of the diagnosed session's case file. Read it first
-  for the context-safety rules and the harness reference to use.
+  for the context-safety rules, discovered record meanings, and extraction
+  commands to use.
 - CANDIDATE: absolute path of one session transcript to examine.
 - SIGNATURE: a list of markers. Each marker is one of:
   - `skill-sequence: <skill A> then <skill B> within <n> turns`
@@ -16,8 +17,8 @@ Inputs:
 
 Procedure:
 1. Apply `references/context-safety.md` to CANDIDATE. Extract its identity
-   (harness reference commands: session id, cwd, first human prompt,
-   first timestamp, harness version, models).
+   with the commands recorded in CASE: session id, cwd, first human prompt,
+   first timestamp, harness version, and models.
 2. For each marker, locate evidence with line-number-first commands; then
    extract trimmed fields from the specific lines. A marker is `hit` when
    you have a `path:line`; `miss` when you searched and found nothing;

+ 7 - 10
skills/diagnosing-superpowers/prompts/skill-timeline.md

@@ -6,17 +6,14 @@ Dimension: Skill timeline
 Build the per-human-turn record of skill and plugin use, then look for gaps.
 
 1. List the human prompts with line numbers and timestamps.
-2. List every skill invocation (Claude Code: `Skill` tool_use `input.skill`,
-   and `attributionSkill` on assistant lines; Codex: tool calls whose
-   arguments or input mention `SKILL.md`; other harnesses: reads of files
-   named `SKILL.md`). Record the line, the skill name, and the human turn
-   it happened in.
+2. Using the skill-invocation and attribution meanings established in the case
+   file, list every explicit invocation, active-skill attribution, or read of a
+   file named `SKILL.md`. Record the line, the skill name, and the human turn it
+   happened in.
 3. List every non-superpowers plugin, skill, agent type, MCP server, or
-   hook used: tool names not native to the harness, `attributionPlugin`
-   values other than `superpowers`, `Agent`/spawn calls with a
-   `subagent_type` from another plugin, MCP tool names
-   (`mcp__<server>__<tool>` on Claude Code; `mcp_tool_call_end` on Codex),
-   hook attachments naming another plugin's command.
+   hook used. Use only the evidenced tool, attribution, agent-dispatch, MCP,
+   and hook meanings recorded in the case file; identify values associated
+   with something other than `superpowers`.
 4. For each human turn, compare the request text against the trigger
    descriptions of the superpowers skills installed (read
    `<install root>/skills/*/SKILL.md` frontmatter `description` lines; the

+ 5 - 7
skills/diagnosing-superpowers/prompts/stumbles.md

@@ -5,10 +5,9 @@ Dimension: Stumbles
 
 Find every point where the session stopped going forward.
 
-Sources, each with the harness-reference command to locate line numbers:
-- tool results marked as errors (Claude Code `"is_error":true`; Codex
-  outputs containing a non-zero exit or an error message; `patch_apply_end`
-  with `success:false`);
+Sources, each using the case file's evidenced record meanings and extraction
+commands to locate line numbers:
+- tool results marked as errors, non-zero exits, or explicit failure records;
 - shell commands that failed (non-zero exit in the result, "command not
   found", "No such file");
 - retries: the same tool call re-issued within the same turn after an
@@ -20,9 +19,8 @@ Sources, each with the harness-reference command to locate line numbers:
   wrong", "I misread");
 - human corrections: a human prompt that contradicts or corrects the
   assistant's immediately preceding action;
-- permission denials, hook failures (`hook_failure` attachments), API
-  errors, rate limits, aborted turns (Codex `turn_aborted`), and context
-  overflow or compaction triggered mid-task.
+- permission denials, hook failures, API errors, rate limits, aborted turns,
+  and context overflow or compaction triggered mid-task.
 
 For each stumble report the line, the turn, what failed, and what happened
 next (recovered in the same turn / recovered later at line N / never

+ 0 - 103
skills/diagnosing-superpowers/references/claude-code-sessions.md

@@ -1,103 +0,0 @@
-# Claude Code session store
-
-Verified against: Claude Code 2.1.247 (transcript `version` field), macOS.
-When a field below is missing from the file in front of you, trust the file
-and say so in coverage notes.
-
-## Where
-
-- Main transcript: `~/.claude/projects/<cwd-slug>/<sessionId>.jsonl`, where
-  `<cwd-slug>` is the working directory with every `/` replaced by `-`
-  (e.g. `/tmp/work` → `-tmp-work`).
-- Subagent transcripts: `~/.claude/projects/<cwd-slug>/<sessionId>/subagents/agent-<agentId>.jsonl`,
-  each with a sibling `agent-<agentId>.meta.json`
-  (`agentType`, `description`, `toolUseId`, `spawnDepth`, optional `model`).
-- Plugin registry: `~/.claude/plugins/installed_plugins.json` — per plugin:
-  `installPath`, `version`, `installedAt`, `lastUpdated`, `gitCommitSha`.
-- The superpowers bootstrap injected into a session is in the
-  `SessionStart` hook attachment (below); its `command` shows the plugin
-  root variable used. A dev checkout loaded with `--plugin-dir` will not be
-  in the registry, so report both the registry entry and the hook evidence.
-
-## Which file is the current session
-
-The most recently modified `.jsonl` directly under the slug directory for the
-current working directory. Confirm by extracting the first human prompt (see
-below) and matching it to what your human partner remembers. If two files
-are close in mtime, show both first prompts and ask.
-
-## Line types
-
-Every line is one JSON object. `type` values seen: `user`, `assistant`,
-`attachment`, `system`, plus session-level records (`permission-mode`,
-`mode`, `bridge-session`, `last-prompt`, `ai-title`, `atis-latch`,
-`pr-link`, `queue-operation`, `relocated`, `worktree-state`).
-
-Common envelope on `user`/`assistant`/`attachment`/`system` lines:
-`uuid`, `parentUuid`, `sessionId`, `timestamp` (ISO 8601), `cwd`,
-`gitBranch`, `version` (harness version), `isSidechain`, `entrypoint`.
-
-| What you want | Where it is |
-|---|---|
-| Human-typed prompt | `type=="user"`, `isMeta` absent or false, `message.content` is a string or a list whose first block is `type:"text"`. Lines whose first block is `tool_result` are tool results, not prompts. `<system-reminder>` text inside a prompt is injected, not typed. Text beginning with `<task-notification>`, `<command-name>`, `<local-command-stdout>`, `<system-reminder>`, or `This session is being continued from a previous conversation` is harness-injected too, even though `isMeta` is absent on those lines — exclude them or your human-turn count will be several times too high. |
-| Human-typed prompt queued mid-turn | `type=="attachment"`, `attachment.type=="queued_command"`, `attachment.origin.kind=="human"`, text in `attachment.prompt`. These are typed while a turn is running and never appear as standalone `user` lines, so they are missing from the list above. Add them to the timeline. |
-| Assistant text / tool calls | `type=="assistant"`, `message.content[]` blocks of `type:"text"` or `type:"tool_use"` (`id`, `name`, `input`). |
-| Tool result | `type=="user"`, `message.content[0].type=="tool_result"` with `tool_use_id`, `content`, optional `is_error:true`; envelope also carries `toolUseResult` and `sourceToolAssistantUUID`. |
-| Model | `message.model` on assistant lines. |
-| Tokens | `message.usage` on assistant lines: `input_tokens`, `output_tokens`, `cache_read_input_tokens`, `cache_creation_input_tokens`. |
-| Skill invocation | `tool_use` block with `name:"Skill"` and `input.skill` (e.g. `superpowers:brainstorming`); the tool result line has `toolUseResult.commandName`. |
-| Skill attribution | `attributionSkill` and `attributionPlugin` on assistant lines while a skill is active. |
-| Subagent dispatch | `tool_use` with `name:"Agent"` (`input.description`, `input.subagent_type`, `input.prompt`); the subagent's own file is matched by `toolUseId` in its `.meta.json`. Subagent lines have `isSidechain:true` and `agentId`. |
-| Hook output | `type=="attachment"`, `attachment.type` `hook_success`/`hook_failure`, `attachment.hookName` (e.g. `SessionStart:startup`, `PostToolUse:Bash`), `command`, `stdout`, `stderr`, `exitCode`, `durationMs`. |
-| Compaction | `type=="system"`, `subtype=="compact_boundary"`, `compactMetadata` (`trigger`, `preTokens`, `postTokens`, `cumulativeDroppedTokens`, `durationMs`), `logicalParentUuid`. |
-| Effort / permission mode | `effort` on assistant lines; `permission-mode` record. |
-
-## Safe extraction
-
-Lines can exceed a megabyte. Apply `context-safety.md` first, with:
-
-```bash
-F=~/.claude/projects/<slug>/<id>.jsonl
-```
-
-With `jq` (preferred):
-
-```bash
-jq -r '.type' "$F" | sort | uniq -c                                    # line-type census
-jq -r 'select(.type=="user" and .isMeta!=true and ((.message.content|type)=="string" or .message.content[0].type=="text"))
-       | select((.message.content|if type=="string" then . else (.[0].text // "") end)
-                | test("^(<task-notification>|<command-name>|<local-command-stdout>|<system-reminder>|This session is being continued)") | not)
-       | "\(input_line_number)\t\(.timestamp)\t\((.message.content|if type=="string" then . else .[0].text end)[0:160])"' "$F"   # human prompts
-jq -r 'select(.type=="attachment" and .attachment.type=="queued_command" and .attachment.origin.kind=="human")
-       | "\(input_line_number)\t\(.timestamp)\t\(.attachment.prompt[0:160])"' "$F"   # human prompts queued mid-turn; merge with the list above
-jq -c 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use")
-       | {name, id, input: (.input|tostring|.[0:120])}' "$F"           # tool calls
-jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use" and .name=="Skill") | .input.skill' "$F"   # skill invocations
-jq -c 'select(.type=="assistant") | {ts:.timestamp, model:.message.model, skill:.attributionSkill,
-       u:(.message.usage|{input_tokens,output_tokens,cache_read_input_tokens,cache_creation_input_tokens})}' "$F"   # per-message usage
-jq -c 'select(.subtype=="compact_boundary") | {line:input_line_number, ts:.timestamp,
-       m:(.compactMetadata|{trigger,preTokens,postTokens,cumulativeDroppedTokens,durationMs})}' "$F"   # compactions (full compactMetadata also has UUID lists; keep this trimmed)
-jq -c 'select(.type=="attachment" and (.attachment.type|startswith("hook"))) | {line:input_line_number, hook:.attachment.hookName, exit:.attachment.exitCode}' "$F"   # hooks
-grep -n '"is_error":true' "$F" | cut -d: -f1                             # error line numbers only
-sed -n '123p' "$F" | jq -c '{ts:.timestamp, first:((.message.content // "") as $c
-       | ($c | if type=="array" then ($c[0] // "") else $c end) | tostring | .[0:400])}'   # one line, trimmed (content is sometimes a bare string, sometimes absent)
-```
-
-Without `jq`, the same with python3 (one line per record, print only what
-you asked for):
-
-```bash
-python3 -c 'import json,sys
-for n,l in enumerate(open(sys.argv[1]),1):
-    o=json.loads(l)
-    if o.get("type")=="assistant":
-        for b in o["message"].get("content",[]):
-            if b.get("type")=="tool_use": print(n, b["name"], str(b.get("input"))[:120])' "$F"
-```
-
-## Subagents
-
-List `~/.claude/projects/<slug>/<id>/subagents/`. For each `agent-*.meta.json`
-print `agentType`, `description`, `model`; the matching `.jsonl` is that
-subagent's transcript and follows the same line format. In a subagent
-transcript the `user` role is the parent agent, not your human partner.

+ 0 - 80
skills/diagnosing-superpowers/references/codex-sessions.md

@@ -1,80 +0,0 @@
-# Codex session store
-
-Verified against: Codex CLI 0.146.0, 0.147.0 and 0.149.0-alpha.4.1 rollouts
-(`cli_version` in `session_meta`), macOS. When a field below is missing from
-the file in front of you, trust the file and say so in coverage notes.
-
-## Where
-
-`~/.codex/sessions/YYYY/MM/DD/rollout-<ISO-timestamp>-<thread-id>.jsonl`.
-Subagent threads are separate rollout files whose `session_meta.payload`
-has `thread_source: "subagent"` and `source.subagent.thread_spawn.parent_thread_id`
-pointing at the parent thread id. Root sessions have `thread_source: "user"`.
-
-## Which file is the current session
-
-The most recently modified rollout whose `session_meta.payload.cwd` is the
-current working directory and whose `thread_source` is `user`. Confirm by
-matching the first `user_message` event to what your human partner
-remembers. Newer rollouts may carry no `user_message` event at all: when
-the human-prompts query under Safe extraction returns nothing, fall back to `response_item` messages with
-`role:"user"` (see Human-typed prompt below) and confirm against the first
-of those instead.
-
-## Line types
-
-Every line is `{timestamp, type, payload}` (some also carry `ordinal`).
-`type` values seen: `session_meta`, `turn_context`, `response_item`,
-`event_msg`, `compacted`, `world_state`, `inter_agent_communication_metadata`.
-
-| What you want | Where it is |
-|---|---|
-| Session identity | `session_meta.payload`: `id`, `session_id`, `cwd`, `originator` (e.g. `Codex Desktop`), `cli_version`, `model_provider`, `thread_source`, `source`, `git` (`commit_hash`, `branch`, `repository_url`), `base_instructions.text`. |
-| Model per turn | `turn_context.payload`: `turn_id`, `model`, `effort`, `cwd`, `approval_policy`, `sandbox_policy`, `multi_agent_version`. Also `event_msg` `thread_settings_applied`. |
-| Human-typed prompt | `event_msg` with `payload.type=="user_message"`: `payload.message`. When that returns nothing — seen on `thread_source: "user"` Codex Desktop rollouts at `cli_version 0.149.0-alpha.4.1`, and on subagent rollouts — fall back to `response_item` messages with `payload.role=="user"`, text in `payload.content[0].text`. `role:"developer"` messages are injected boilerplate, not typed, and so is any fallback text that begins with a tag such as `<subagent_notification>`, `<environment_context>`, `<skill>` or `<recommended_plugins>`. On a subagent rollout the fallback text is the parent agent's dispatch prompt, not your human partner's. |
-| Assistant text | `event_msg` `agent_message` (`payload.message`, `payload.phase`) or `response_item` `message` with `role:"assistant"`. |
-| Tool calls | `response_item` with `payload.type` `function_call` (`name`, `arguments`, `call_id`) or `custom_tool_call` (`name`, `input`, `call_id`); outputs are `function_call_output` / `custom_tool_call_output` matched by `call_id`. Also `event_msg` `patch_apply_end` (`success`, `changes`), `web_search_end`, `mcp_tool_call_end` (`invocation.server`, `invocation.tool`). |
-| Turn timing | `event_msg` `task_started` (`turn_id`, `started_at`, `model_context_window`) and `task_complete` (`duration_ms`, `time_to_first_token_ms`, `last_agent_message`); `turn_aborted` (`reason`, `duration_ms`). |
-| Tokens | `event_msg` `token_count`: `payload.info.total_token_usage` (cumulative; keys include `input_tokens`, `cached_input_tokens`, `output_tokens`) and `payload.rate_limits`. |
-| Compaction | a `compacted` line (`window_id`, `previous_window_id`, `replacement_history`) and an `event_msg` `context_compacted`. |
-| Subagents | `event_msg` `sub_agent_activity` (`agent_thread_id`, `agent_path`, `kind`); `response_item` `agent_message` with `author`/`recipient`; the child's own rollout file (see Where). |
-| Skill use | No attribution field. Look for `SKILL.md` in `function_call.arguments` / `custom_tool_call.input` and in `world_state`/`session_meta` instruction text. |
-| Reasoning | `response_item` `reasoning` (`summary[].text`; `encrypted_content` is opaque). |
-
-## Safe extraction
-
-Rollouts reach hundreds of megabytes; `compacted` lines embed whole
-histories. Apply `context-safety.md` first, with:
-
-```bash
-F=~/.codex/sessions/YYYY/MM/DD/rollout-....jsonl
-```
-
-With `jq`:
-
-```bash
-head -1 "$F" | jq '.payload | {id, cwd, originator, cli_version, model_provider, thread_source, git}'   # identity
-jq -r '.type + "/" + (.payload.type // "")' "$F" | sort | uniq -c                                       # census
-jq -r 'select(.type=="event_msg" and .payload.type=="user_message") | "\(input_line_number)\t\(.timestamp)\t\(.payload.message[0:160])"' "$F"   # human prompts
-jq -r 'select(.type=="response_item" and .payload.type=="message" and .payload.role=="user")
-       | "\(input_line_number)\t\(.timestamp)\t\((.payload.content[0].text // "")[0:160])"' "$F"   # human prompts, fallback when the line above returns nothing; skip rows whose text starts with a `<tag>`
-jq -r 'select(.type=="turn_context") | "\(.timestamp)\t\(.payload.model)\t\(.payload.effort)"' "$F"    # model per turn
-jq -c 'select(.type=="response_item" and (.payload.type=="function_call" or .payload.type=="custom_tool_call"))
-       | {line:input_line_number, name:.payload.name, args:((.payload.arguments // .payload.input)|tostring|.[0:120])}' "$F"   # tool calls
-jq -c 'select(.payload.type=="task_complete" or .payload.type=="turn_aborted") | {ts:.timestamp, type:.payload.type, ms:.payload.duration_ms}' "$F"   # turn timing
-jq -c 'select(.payload.type=="token_count") | {ts:.timestamp, t:.payload.info.total_token_usage}' "$F"   # tokens (cumulative)
-grep -n '"type":"compacted"\|"context_compacted"' "$F" | cut -d: -f1       # compaction line numbers
-grep -n 'SKILL\.md' "$F" | cut -d: -f1                                    # skill-read line numbers
-sed -n '123p' "$F" | jq -c '{ts:.timestamp, type, p:(.payload|tostring|.[0:400])}'   # one line, trimmed
-```
-
-Find a thread's subagent rollouts (filenames only, never content):
-
-```bash
-grep -l '"parent_thread_id":"<thread-id>"' ~/.codex/sessions/*/*/*/rollout-*.jsonl
-```
-
-A subagent rollout can carry no `event_msg` `user_message` at all — the
-parent agent's dispatch prompt instead shows up as a `response_item`
-`message` with `role:"user"`. If a `user_message` event is present, it is
-from the parent agent, not your human partner.

+ 6 - 6
skills/diagnosing-superpowers/references/context-safety.md

@@ -1,9 +1,9 @@
 # Context safety for session transcripts
 
-One transcript line can exceed a megabyte; a Codex `compacted` line can
-embed a whole history. Printing one whole line can overflow the context of
-the session doing the diagnosis. Every reader of a session file, controller or subagent,
-follows these rules for every file, every time.
+One transcript record can exceed a megabyte or embed a whole history. Printing
+one whole record can overflow the context of the session doing the diagnosis.
+Every reader of a session file, controller or subagent, follows these rules for
+every file, every time.
 
 1. **Measure before reading.**
 
@@ -15,8 +15,8 @@ follows these rules for every file, every time.
 2. **Never `cat` or `grep` for content.** Get line numbers and counts
    first (`grep -n … | cut -d: -f1`, `jq -r '.type' | sort | uniq -c`),
    then small fields from specific lines (`sed -n Np | jq -c '{…}'` or
-   `| cut -c1-500`). The harness reference lists the field-extraction
-   commands.
+   `| cut -c1-500`). Use the field-extraction commands established during
+   discovery for the source in front of you.
 3. **Narrow anything over 500 characters.** If a command returns more than
    500 characters for one record, tighten the field or the slice.
 4. **Read-only.** Never modify, move, or delete a session file.

+ 0 - 30
skills/diagnosing-superpowers/references/other-harnesses.md

@@ -1,30 +0,0 @@
-# Other harnesses: discover, then report what you found
-
-This file is for any harness without a verified reference in this
-directory. You know your own harness better than this file does. Use that
-knowledge, and write down exactly what you found so the report reader can
-judge it.
-
-## Procedure
-
-1. **Ask the harness.** Many harnesses expose a session or history command
-   (`<harness> session list`, `/sessions`, a "resume" picker). Use it to get
-   the session id and, if shown, the file path.
-2. **Look under the harness's config directory** (`~/.<harness>/`,
-   `~/.config/<harness>/`, `~/.local/share/<harness>/`) for `sessions`,
-   `history`, `chats`, `threads`, or `projects` directories holding `.jsonl`
-   or `.json` files.
-3. **Confirm a candidate** by extracting its first human message with a
-   size-safe command (`head -c 2000`, or `jq` on the first record) and
-   matching it to what your human partner remembers. Treat every candidate
-   like the verified stores: apply `context-safety.md` before anything
-   else.
-4. **Map the fields you need** by reading a handful of records with `jq -c
-   'keys'` or `head -c`: human prompt, assistant text, tool call and result,
-   model, harness version, timestamps, subagent linkage, compaction.
-5. **Record in the case file and the report's coverage notes**: the store
-   path, the layout you inferred, which of the fields above you could and
-   could not find, and your confidence. Field-level claims in the report
-   are marked "inferred from the file, not a documented format".
-6. **If you cannot find the store**, say so and ask your human partner for
-   the path. Do not guess a layout from another harness.

+ 27 - 0
skills/diagnosing-superpowers/references/session-discovery.md

@@ -0,0 +1,27 @@
+# Discover the session history
+
+Resolve the session your human partner named using the tools and information
+available in this environment. Your knowledge can suggest where to look; verify
+the result against the actual history.
+
+Use the harness's exposed session tools, configured storage, local help,
+documentation, or bounded filesystem inspection. Measure files before reading
+their content and follow context-safety.md. Inspect archives or indexes when the
+environment points to them. A supplied usable path does not need another search.
+
+Confirm identity using the available session id, working directory, timestamps,
+and matching conversation content. Recency alone is not confirmation. Distinguish
+the requested session from its children and unrelated candidates. Ask for a
+missing identifying fact when the available evidence cannot distinguish them.
+
+Establish the record meanings needed for the requested investigation from
+observed records or documentation. Distinguish human messages from injected
+messages, tool results, and a parent agent's dispatch. Match tool calls to their
+results. Establish usage-counter semantics before calculating totals. Do not
+infer a format from another harness or turn a missing field into a zero.
+
+Record the exact sources, relevant field meanings, supporting record locations,
+associated sessions, rejected plausible candidates, and unresolved information
+in the case file. Subsequent readers use that record rather than repeating
+discovery. If history is missing, inaccessible, or ambiguous, state the specific
+limitation and ask for the missing path, export, or identifying detail.

+ 14 - 3
skills/diagnosing-superpowers/templates/case.md

@@ -41,6 +41,17 @@ Session still running at read time: yes | no (mtime <ISO>, lines <N>)
 - Follow `references/context-safety.md` before reading any file listed here.
 - In a subagent transcript, "user" is the parent agent.
 
-## Harness reference to use
-
-<references/claude-code-sessions.md | references/codex-sessions.md | references/other-harnesses.md>
+## Discovered sources and record meanings
+
+- Sources consulted: <absolute path, tool, help, or documentation source>
+- Extraction commands or queries: <bounded commands or tool queries used for each source>
+- Target identity evidence: <session id, working directory, timestamps, matching content, and supporting record locations>
+- Associated sessions: <session id, relationship, and supporting record locations, or "none found">
+- Human messages: <record shape and evidence for its meaning>
+- Injected messages and parent dispatches: <record shape and evidence for its meaning>
+- Assistant messages: <record shape and evidence for its meaning>
+- Tool calls and results: <record shapes, how they match, and evidence for those meanings>
+- Usage counters: <fields, incremental or cumulative semantics, units, and evidence, or "unavailable">
+- Timing: <fields, units, event boundaries, and evidence, or "unavailable">
+- Other relevant records: <models, versions, compactions, or other meanings and evidence>
+- Unresolved information: <missing, inaccessible, ambiguous, or absent information, or "none">

+ 23 - 3
tests/diagnosing-superpowers/test-skill-structure.sh

@@ -78,9 +78,7 @@ fi
 
 # --- expected files -------------------------------------------------------
 expected_files=(
-  references/claude-code-sessions.md
-  references/codex-sessions.md
-  references/other-harnesses.md
+  references/session-discovery.md
   references/context-safety.md
   references/github-issues.md
   prompts/analyst-common.md
@@ -107,6 +105,28 @@ for rel in "${expected_files[@]}"; do
   fi
 done
 
+# --- removed harness recipes stay removed --------------------------------
+removed_files=(
+  references/claude-code-sessions.md
+  references/codex-sessions.md
+  references/other-harnesses.md
+)
+for rel in "${removed_files[@]}"; do
+  if [ ! -e "$SKILL_DIR/$rel" ]; then
+    pass "removed reference absent: $rel"
+  else
+    fail "removed reference absent: $rel"
+  fi
+done
+
+removed_reference_hits="$(grep -rn -E 'references/(claude-code-sessions|codex-sessions|other-harnesses)\.md' "$SKILL_DIR" --include='*.md' 2>/dev/null || true)"
+if [ -z "$removed_reference_hits" ]; then
+  pass "active skill prose has no references to removed harness recipes"
+else
+  fail "active skill prose has no references to removed harness recipes"
+  printf '%s\n' "$removed_reference_hits" | head -10 | sed 's/^/    /'
+fi
+
 # --- no local paths or names in shipped files ----------------------------
 leaks="$(grep -rn -E '/Users/|/home/|jesse' "$SKILL_DIR" "$SCRIPT_DIR" --exclude=test-skill-structure.sh 2>/dev/null || true)"
 if [ -z "$leaks" ]; then