From f5ceeecdb0dca396475c2ea9d28c2aa3f8a9faf6 Mon Sep 17 00:00:00 2001 From: Udale-Ameh Ojimaojo Date: Wed, 10 Jun 2026 00:44:31 +0100 Subject: [PATCH 1/2] Slim SKILL.md core and add cross-platform resume reference SKILL.md drops from 11391 to 6558 bytes (-42%) by merging the triplicated evidence prose into Core Workflow and moving the detailed provenance bookkeeping, long-tail evidence rules, and the static idempotency contract into references/evidence-and-provenance.md, leaving one-line pointers in the core file. Also broadens the frontmatter description to trigger on locating, reading, inspecting, auditing, or reviewing prior sessions and on cross-agent asks; adds a provenance self-check step (canonical path skills/agent-session-resume/scripts/skill-provenance.py); and adds references/cross-platform.md with a workflow for multi-runtime resume/audit asks (independent per-adapter discovery, UTC-epoch normalization, merged timeline, per-runtime evidence attribution, overlap dedupe, single task-status breakdown). Co-Authored-By: Claude Fable 5 --- skills/agent-session-resume/SKILL.md | 147 ++++++------------ .../references/cross-platform.md | 72 +++++++++ .../references/evidence-and-provenance.md | 49 ++++++ 3 files changed, 166 insertions(+), 102 deletions(-) create mode 100644 skills/agent-session-resume/references/cross-platform.md create mode 100644 skills/agent-session-resume/references/evidence-and-provenance.md diff --git a/skills/agent-session-resume/SKILL.md b/skills/agent-session-resume/SKILL.md index 92e0d27..c5c8134 100644 --- a/skills/agent-session-resume/SKILL.md +++ b/skills/agent-session-resume/SKILL.md @@ -1,90 +1,55 @@ --- name: agent-session-resume -description: Use when continuing work from a previous AI coding-agent session, handoff transcript, chat log, exported conversation, saved artifact set, or session summary. +description: Use when continuing, resuming, locating, reading, inspecting, auditing, or reviewing a previous AI coding-agent session, handoff transcript, chat log, exported conversation, saved artifact set, or session summary, on any platform (Claude Code, Codex, Cursor, Antigravity, OpenCode) or across several platforms in one ask, such as reviewing threads across Claude and Codex. --- # Agent Session Resume ## Purpose -Resume prior coding-agent work with continuity. The agent must reconstruct what happened before acting, then continue from the real stopping point. +Resume or audit prior coding-agent work with continuity. Reconstruct what happened before acting, then continue from the real stopping point. ## Core Workflow -1. Identify the source. - - If the user names a platform, read the matching file in `references/`. - - If no platform is named, inspect the workspace for session folders, exports, summaries, and artifacts. - - If a session title or name is provided, prefer exact or fuzzy title matches over recency. - -2. Locate the transcript or best available substitute. - - Prefer a full transcript over summaries. - - Prefer workspace-local session data over global history when both are plausible. - - Prefer explicit user-provided paths over discovered paths. - -3. Read the full available session record before taking action. - - For large transcripts, first build an inventory of files, event types, timestamps, sidecars, and candidate evidence; then read the evidence-bearing slices until the complete record has been accounted for. - - Include user messages, assistant messages, tool calls, tool outputs, summaries, plans, and artifacts that explain decisions. - - Full coverage means no relevant evidence was skipped. It does not require pasting giant transcript records, raw metadata, or entire tool-output files into context when a bounded search or slice captures the evidence. - - If a large output is summarized instead of fully loaded, say so in the resume report and identify the file/event searched. - - Do not edit files, run fix commands, or repeat prior work before this pass is complete. - -4. Record skill provenance. - - Name the loaded skill file path in the checkpoint when the runtime exposes it, for example a `skills/agent-session-resume/SKILL.md` path. If the runtime does not expose the loaded path, write `unknown`. - - Name a source/version marker when available: plugin manifest version, marketplace package version, git tag or commit, package source, or checksum from the loaded skill file. If none is available, write `unknown`. - - Do not infer the active skill version from an unrelated repository checkout, local clone, docs page, or install command. Label those as candidate sources unless you can prove they are the loaded artifact. - - When comparing Codex and Claude behavior, compare the known install paths and reported source/version markers from each runtime. Common standalone paths are `${CODEX_HOME:-$HOME/.codex}/skills/agent-session-resume/SKILL.md` for Codex and `$HOME/.claude/skills/agent-session-resume/SKILL.md` for Claude Code. Claude Code plugin installs may expose a plugin-managed path or only the plugin manifest/version. - - After updating installed skill files, assume an already-running agent may still be using the previous loaded instructions until the app, CLI, plugin, or session is restarted or reloaded. - -5. Reconstruct context. - - Summarize the session goal. - - List important decisions, constraints, style choices, and user preferences. - - Identify completed work, changed files, commands run, tests run, and verification results. - - Identify the exact stopping point, including the last command, edit, failure, or pending instruction. - - Attach evidence references to claims about work state. Prefer `path/to/file.ext:L10-L20` for files, transcript line numbers for session records, command names plus transcript/tool-output lines for verification, and explicit "not found" or "not checked yet" notes when evidence is missing. - - Treat prior resume reports, summaries, and handoffs as orientation aids and claims, not primary evidence. Re-verify their task status claims against transcript events, repo files, git status, GitHub state, command output, fixtures, or other primary sources before relying on them. - - If a prior-report claim cannot be checked against a primary source, label it as unverified instead of presenting it as fact. - - Preserve explicit user deferrals such as "skip", "park", "leave out", "not now", "later", "hold", or "out of scope" with evidence, the deferred scope, and any condition for reopening it. - -6. Extract tasks. - - Capture explicit TODOs, checklists, plans, and open questions. - - Infer implicit tasks from failing tests, unfinished edits, "next step" language, and partially applied changes. - - Classify concrete action items separately; do not replace a specific unfinished task with a broad category. - - Track explicitly deferred or parked work separately from ordinary `NOT DONE` work. Do not reintroduce deferred scope just because the user says "proceed", "continue", or another vague go-ahead; ask for confirmation unless the user clearly names the parked scope or its reopening condition has been met. - - Classify each item as: - - `DONE`: completed and verified, or clearly no longer needed. - - `PARTIALLY DONE`: started but missing implementation, tests, review, commit, push, or user confirmation. - - `NOT DONE`: not started or only discussed. - -7. Validate against the workspace. - - Inspect git status before editing and mention the result in the checkpoint. - - Read files touched or discussed in the prior session. - - Preserve unrelated user changes. - - If the worktree is dirty before you start, identify likely pre-existing changes, keep them out of unrelated commits, and do not overwrite, reset, revert, or stage them unless the user explicitly asks. If checkout, merge, or branch work would collide with dirty files, use a separate worktree or ask before proceeding. - - If transcript claims conflict with the current files, trust current files for implementation state and report the discrepancy in the mismatch format below. - -8. Continue from the first unfinished step. - - Do not repeat completed work. - - Follow the established approach, style, naming, and decisions unless they are clearly broken. - - If context is missing, inspect related files and logs. - - Ask the user only when progress is blocked by missing information or an unsafe choice. +1. Run a provenance self-check. + - Run `python3 skills/agent-session-resume/scripts/skill-provenance.py` when available. + - Otherwise compare the loaded SKILL.md path and size against the known install paths under `$HOME/.claude` and `${CODEX_HOME:-$HOME/.codex}`. + - Report staleness on the `Loaded skill` line of the resume report. Details: `references/evidence-and-provenance.md`. + +2. Identify the source. If the user names a platform, read the matching file in `references/`; if the ask spans platforms, read `references/cross-platform.md`. Otherwise inspect the workspace for session folders, exports, summaries, and artifacts. When a session title is given, prefer exact or fuzzy title matches over recency. + +3. Locate the transcript or best substitute. Prefer full transcripts over summaries, workspace-local session data over global history, and explicit user-provided paths over discovered paths. + +4. Read the full available session record before acting. For large transcripts, inventory files, event types, and timestamps first, then read the evidence-bearing slices until the record is accounted for. Full coverage means no relevant evidence skipped; bounded searches and slices are fine for giant records, but say so and name the file/event. Do not edit files or repeat prior work before this pass is complete. + +5. Record loaded-skill provenance in the report: path and source/version marker, or `unknown`, never a guess. Details: `references/evidence-and-provenance.md`. + +6. Reconstruct context. Summarize the goal, decisions, constraints, and preferences; identify completed work, changed files, commands and tests run; pin the exact stopping point. Every work-state claim carries an evidence ref (`src/file.ts:L20-L35`, transcript lines, command output, or explicit "not checked yet"). Prior resume reports, summaries, and handoffs are claims, not primary evidence: re-verify against transcripts, files, git state, or command output, or label them unverified. Preserve explicit user deferrals ("skip", "park", "not now", "hold") with evidence, scope, and reopen condition. + +7. Extract tasks. Capture explicit TODOs, plans, and open questions; infer implicit tasks from failing tests, unfinished edits, and "next step" language. Keep specific unfinished tasks specific. Track deferred work separately from `NOT DONE`. Classify: `DONE` (completed and verified, or no longer needed), `PARTIALLY DONE` (started but missing implementation, tests, review, commit, push, or confirmation), `NOT DONE` (not started or only discussed). + +8. Validate against the workspace. Inspect git status before editing and mention it in the checkpoint; read files the prior session touched. Preserve unrelated user changes in a dirty worktree; use a separate worktree or ask before colliding work. If transcript claims conflict with current files, trust current files and report the mismatch. + +9. Continue from the first unfinished step. Do not repeat completed work; follow the established approach and style unless clearly broken. Ask the user only when blocked by missing information or an unsafe choice. ## Resume Modes -Use the user's prompt to decide how far to go after the checkpoint: +Decide from the user's prompt how far to go after the checkpoint: -- `Report-only`: If the user asks what happened, where the prior session left off, what is done versus pending, or asks to check a previous session without asking for edits, stop after the required resume report and clear next action. -- `Continue-edit`: If the user asks to continue, resume, fix, implement, open a PR, run tests, or otherwise act on the unfinished work, provide the required resume report first, then continue from the first unfinished safe step. -- `Quick resume`: Use when the user asks for a status report, latest stopping point, or task breakdown. Prefer a compact source inventory, task classification, and next action. -- `Deep resume`: Use when the user asks to continue implementation, when the source is ambiguous, or when current files may have drifted. Read the full available record, inspect current git state and relevant files, then continue. +- `Report-only`: the ask is what happened, done versus pending, or to check/audit/review a prior session without edits. Stop after the resume report and clear next action. +- `Continue-edit`: the ask is to continue, fix, implement, open a PR, or run tests. Report first, then continue from the first unfinished safe step. +- `Quick resume`: status report or task breakdown. Prefer a compact source inventory, task classification, and next action. +- `Deep resume`: implementation continues, the source is ambiguous, or files may have drifted. Read the full record and current git state, then continue. ## Platform References -- Claude Code: read `references/claude-code.md`. -- Codex: read `references/codex.md`. -- Cursor: read `references/cursor.md`. -- Antigravity: read `references/antigravity.md`. -- OpenCode: read `references/opencode.md`. -- GitHub Copilot: read `references/github-copilot.md`. +- Claude Code: `references/claude-code.md` +- Codex: `references/codex.md` +- Cursor: `references/cursor.md` +- Antigravity: `references/antigravity.md` +- OpenCode: `references/opencode.md` +- GitHub Copilot: `references/github-copilot.md` +- Cross-platform / multi-agent asks: `references/cross-platform.md` ## Required Response Shape @@ -94,20 +59,18 @@ Before continuing execution, report: ## Brief context summary - Goal: -- Loaded skill: path=; source/version= +- Loaded skill: path=; source/version= - Source reviewed: - Current workspace check: -- Transcript/current repo mismatches: none found - - Or: - transcript: ; current repo: ; action: -- User deferrals: none found - - Or: - user said ; evidence: ; reopen condition: +- Transcript/current repo mismatches: +- User deferrals: - Stopping point: ## Task status breakdown -- DONE: - evidence: ; verification: . -- PARTIALLY DONE: - evidence: ; missing: . -- NOT DONE: - evidence: . +- DONE: - evidence: ; verification: . +- PARTIALLY DONE: - evidence: ; missing: . +- NOT DONE: - evidence: . ## Clear next action @@ -115,33 +78,13 @@ Before continuing execution, report: - Blocked: ``` -Then continue immediately unless blocked. - -## Evidence Rules - -- Every task status line must include `evidence:` with at least one concrete source reference. -- `DONE` requires evidence of completion, not just a plan or intention. -- `PARTIALLY DONE` requires evidence that work started plus the missing completion or verification. -- `NOT DONE` requires evidence from an explicit TODO, failing command, missing artifact, or transcript gap. -- If current-repo verification has not happened yet, say so plainly instead of implying the transcript is current. -- The loaded skill path and source/version marker may be `unknown`, but must not be guessed. If only a candidate install path is known, say `unknown` for the loaded path and mention the candidate path separately. -- User deferrals require evidence from the transcript, handoff, or active prompt. Preserve the deferred scope even when the rest of the work is ready to continue. -- Use compact, stable references so a person or script can trace the claim: `session.jsonl:L4`, `handoff.md:L7-L10`, `src/file.ts:L20-L35`, or `git status --short --branch`. -- Prior resume reports can help route the investigation, but they do not prove task state by themselves. Cite the primary evidence that verifies the claim, or mark the claim unverified when primary evidence is unavailable. - -## Static Idempotency Contract - -- For static sources, repeated resumes over the same unchanged transcript, artifacts, and workspace should converge on the same task status breakdown and next-action class. -- Exact wording may vary, but evidence references, task classifications, mismatch handling, and whether the next action is blocked or actionable should remain stable. -- Static idempotency does not apply to live or active transcripts, changing repositories, remote GitHub state, running commands, or other sources that may drift between runs. +Then continue immediately unless blocked. Evidence rules and the static idempotency contract: `references/evidence-and-provenance.md`. ## Guardrails -- Never assume the newest file is the right transcript if the user supplied a title or path. -- Never summarize from filenames alone. +- Never assume the newest file is the right transcript when the user supplied a title or path. +- Never summarize from filenames alone or treat a compact summary as equivalent to an available full transcript. - Never reset, revert, or discard existing changes unless the user explicitly asks. -- Never treat a compact summary as equivalent to the full transcript when a full transcript is available. -- Never mark a task `DONE` only because it was planned. -- Never mark a task `PARTIALLY DONE` only because it appeared in a plan; there must be evidence work started. +- Never mark a task `DONE` or `PARTIALLY DONE` from a plan alone; status requires evidence of completion or started work. - Never omit transcript/current-repo mismatches when the transcript and checked files disagree. -- Never unpark explicitly deferred scope from a vague prompt such as "Proceed" or "continue"; confirm the user wants that parked work reopened. +- Never unpark deferred scope from a vague "proceed" or "continue"; confirm the user wants that parked work reopened. diff --git a/skills/agent-session-resume/references/cross-platform.md b/skills/agent-session-resume/references/cross-platform.md new file mode 100644 index 0000000..0f414d1 --- /dev/null +++ b/skills/agent-session-resume/references/cross-platform.md @@ -0,0 +1,72 @@ +# Cross-Platform Resume + +Use this workflow when one ask spans multiple agent platforms: "review my threads across Claude and Codex", "what did my agents do on this repo last week", or any resume/audit naming more than one runtime. + +## Detect the Span + +Treat the ask as cross-platform when the user names two or more runtimes, says "all my agents/sessions/threads", or when discovery for one named platform surfaces a matching session on another runtime for the same repo and time window. State the platform set you are covering in the context summary before reading transcripts. + +## Discover Per Platform + +Run each platform adapter's discovery independently and completely. Do not let one runtime's results stop or narrow discovery on another. + +- Claude Code: `references/claude-code.md` +- Codex: `references/codex.md` +- Cursor: `references/cursor.md` +- Antigravity: `references/antigravity.md` +- OpenCode: `references/opencode.md` + +Keep one candidate list per runtime, each entry carrying session ID, transcript path, cwd, title, and updated time. + +## Normalize Timestamps + +Runtimes mix ISO-8601 strings, local times, and file mtimes. Convert every candidate's time to UTC epoch seconds before comparing across runtimes: + +```bash +# ISO-8601 -> epoch (BSD date first, GNU date fallback) +date -j -u -f '%Y-%m-%dT%H:%M:%S' '2026-06-09T14:03:11' +%s 2>/dev/null \ + || date -u -d '2026-06-09T14:03:11' +%s +# file mtime -> epoch +stat -f '%m' "$transcript" 2>/dev/null || stat -c '%Y' "$transcript" +``` + +Never rank candidates from mixed-format timestamp strings. + +## Build One Merged Timeline + +Merge the per-runtime candidate lists into a single timeline keyed by (cwd match, time window). One TSV line per session, sorted by epoch: + +```bash +# epoch runtime cwd transcript path title +sort -n /tmp/merged-sessions.tsv | column -t -s $'\t' +``` + +Group sessions that share a cwd (or parent/child cwd) into per-repo lanes, then read them in time order. The merged timeline decides reading order; the per-runtime adapters decide how to read each transcript safely. + +## Attribute Evidence + +Every evidence item names its runtime and transcript path, not just a line number: + +- `codex: ~/.codex/sessions/2026/06/09/rollout-.jsonl:L42` +- `claude-code: ~/.claude/projects//.jsonl:L17` + +Never cite "the transcript" when more than one runtime is in play. + +## Dedupe Overlapping Work + +Same repo, overlapping time window, and same files touched usually means one task seen from two runtimes (for example, work started in Claude Code and reviewed or continued in Codex). For each suspected overlap: + +1. Compare the touched-file sets and the commands run in both transcripts. +2. If they describe the same task, merge into one task entry, keep both runtimes' evidence refs, and note which runtime carried it furthest. +3. If you cannot confirm they are the same task, keep them as separate entries and flag the possible overlap in the context summary. + +Do not double-count merged work in the task status breakdown, and do not let a stale transcript from one runtime downgrade work a later session completed. + +## Report + +Produce one task-status breakdown (the Required Response Shape in SKILL.md) covering all runtimes: + +- `Source reviewed` lists each runtime with its transcript paths. +- Each `DONE` / `PARTIALLY DONE` / `NOT DONE` line cites per-runtime evidence refs. +- Mismatch and deferral lines name the runtime whose transcript carries the evidence. +- The clear next action is a single step, even when the prior work spans runtimes; name the runtime context only if it changes what to do. diff --git a/skills/agent-session-resume/references/evidence-and-provenance.md b/skills/agent-session-resume/references/evidence-and-provenance.md new file mode 100644 index 0000000..7ddc39f --- /dev/null +++ b/skills/agent-session-resume/references/evidence-and-provenance.md @@ -0,0 +1,49 @@ +# Evidence and Provenance + +Use this reference for the detailed rules behind the `Loaded skill` line, evidence references, and repeat-resume stability. SKILL.md carries the workflow; this file carries the long tail. + +## Provenance Self-Check + +Run the bundled checker before writing the resume report: + +```bash +python3 skills/agent-session-resume/scripts/skill-provenance.py +``` + +Run it from the root that contains `skills/agent-session-resume/`. If the script is not at that path (older installs keep it at `scripts/skill-provenance.py` in the repo root), check there before falling back to manual comparison. It compares the repo copy of SKILL.md against the Codex and Claude install paths and prints bytes, lines, and SHA-256 per surface. Pass `--repo-root`, `--codex-home`, `--claude-home`, or `--format json` to adjust. + +If the script is unavailable, compare manually: + +```bash +wc -c "$HOME/.claude/skills/agent-session-resume/SKILL.md" \ + "${CODEX_HOME:-$HOME/.codex}/skills/agent-session-resume/SKILL.md" 2>/dev/null +shasum -a 256 path/to/loaded/SKILL.md path/to/candidate/SKILL.md 2>/dev/null +``` + +Report the outcome on the `Loaded skill` line: `matches-repo`, `differs-from-repo` (stale), `missing`, or `unknown`. + +## Recording Skill Provenance + +- Name the loaded skill file path in the checkpoint when the runtime exposes it, for example a `skills/agent-session-resume/SKILL.md` path. If the runtime does not expose the loaded path, write `unknown`. +- Name a source/version marker when available: plugin manifest version, marketplace package version, git tag or commit, package source, or checksum from the loaded skill file. If none is available, write `unknown`. +- Do not infer the active skill version from an unrelated repository checkout, local clone, docs page, or install command. Label those as candidate sources unless you can prove they are the loaded artifact. +- When comparing Codex and Claude behavior, compare the known install paths and reported source/version markers from each runtime. Common standalone paths are `${CODEX_HOME:-$HOME/.codex}/skills/agent-session-resume/SKILL.md` for Codex and `$HOME/.claude/skills/agent-session-resume/SKILL.md` for Claude Code. Claude Code plugin installs may expose a plugin-managed path or only the plugin manifest/version. +- After updating installed skill files, assume an already-running agent may still be using the previous loaded instructions until the app, CLI, plugin, or session is restarted or reloaded. + +## Evidence Rules + +- Every task status line must include `evidence:` with at least one concrete source reference. +- `DONE` requires evidence of completion, not just a plan or intention. +- `PARTIALLY DONE` requires evidence that work started plus the missing completion or verification. +- `NOT DONE` requires evidence from an explicit TODO, failing command, missing artifact, or transcript gap. +- If current-repo verification has not happened yet, say so plainly instead of implying the transcript is current. +- The loaded skill path and source/version marker may be `unknown`, but must not be guessed. If only a candidate install path is known, say `unknown` for the loaded path and mention the candidate path separately. +- User deferrals require evidence from the transcript, handoff, or active prompt. Preserve the deferred scope even when the rest of the work is ready to continue. Do not reintroduce deferred scope from a vague go-ahead such as "proceed"; ask for confirmation unless the user clearly names the parked scope or its reopening condition has been met. +- Use compact, stable references so a person or script can trace the claim: `session.jsonl:L4`, `handoff.md:L7-L10`, `src/file.ts:L20-L35`, or `git status --short --branch`. +- Prior resume reports can help route the investigation, but they do not prove task state by themselves. Cite the primary evidence that verifies the claim, or mark the claim unverified when primary evidence is unavailable. + +## Static Idempotency Contract + +- For static sources, repeated resumes over the same unchanged transcript, artifacts, and workspace should converge on the same task status breakdown and next-action class. +- Exact wording may vary, but evidence references, task classifications, mismatch handling, and whether the next action is blocked or actionable should remain stable. +- Static idempotency does not apply to live or active transcripts, changing repositories, remote GitHub state, running commands, or other sources that may drift between runs. From bad4e9f424e2690dbf3d35e795a95fb3832a2486 Mon Sep 17 00:00:00 2001 From: Udale-Ameh Ojimaojo Date: Wed, 10 Jun 2026 01:33:14 +0100 Subject: [PATCH 2/2] Fix timestamp normalization recipe, document windowing/merge, and guard trigger description regressions Co-Authored-By: Claude Fable 5 --- scripts/validate-trigger-matrix.py | 40 ++++++++++++++++++- .../references/cross-platform.md | 38 ++++++++++++++---- tests/trigger-matrix.json | 18 +++++++++ 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/scripts/validate-trigger-matrix.py b/scripts/validate-trigger-matrix.py index 7bd1a96..3ae0bcc 100644 --- a/scripts/validate-trigger-matrix.py +++ b/scripts/validate-trigger-matrix.py @@ -4,12 +4,14 @@ from __future__ import annotations import json +import re import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] MATRIX = ROOT / "tests" / "trigger-matrix.json" +SKILL_MD = ROOT / "skills" / "agent-session-resume" / "SKILL.md" REQUIRED_TRIGGER_CATEGORIES = { "explicit-skill", @@ -17,6 +19,17 @@ "platform-specific", "handoff-artifact", "paraphrase", + "locate", + "audit", + "cross-platform", +} + +# Verb stems the SKILL.md description must keep so locate/audit/review asks +# still trigger ("locat" covers locating/locate, and so on). +REQUIRED_DESCRIPTION_VERBS = { + "locat": "locating", + "audit": "auditing", + "review": "reviewing", } REQUIRED_NEGATIVE_CATEGORIES = { "general-coding", @@ -79,6 +92,28 @@ def validate_cases(name: str, minimum: int, seen_ids: set[str]) -> set[str]: return categories +def validate_skill_description() -> None: + if not SKILL_MD.exists(): + fail(f"missing skill file: {SKILL_MD.relative_to(ROOT)}") + text = SKILL_MD.read_text(encoding="utf-8") + match = re.search(r"^description:\s*(\S.*)$", text, flags=re.MULTILINE) + if not match: + fail("SKILL.md frontmatter must define a description") + description = match.group(1).strip().lower() + + missing_verbs = sorted( + label for stem, label in REQUIRED_DESCRIPTION_VERBS.items() if stem not in description + ) + if missing_verbs: + fail(f"SKILL.md description must keep trigger verbs: {', '.join(missing_verbs)}") + + has_cross_platform_clause = "across" in description and ( + "platforms" in description or ("claude" in description and "codex" in description) + ) + if not has_cross_platform_clause: + fail("SKILL.md description must keep a cross-platform clause (e.g. across several platforms)") + + def main() -> None: data = load_matrix() if data.get("version") != 1: @@ -107,9 +142,12 @@ def main() -> None: if missing_platforms: fail(f"missing platform trigger coverage: {', '.join(sorted(missing_platforms))}") + validate_skill_description() + print( f"validated {len(data['should_trigger'])} trigger and " - f"{len(data['should_not_trigger'])} non-trigger prompts" + f"{len(data['should_not_trigger'])} non-trigger prompts " + "plus SKILL.md description coverage" ) diff --git a/skills/agent-session-resume/references/cross-platform.md b/skills/agent-session-resume/references/cross-platform.md index 0f414d1..74c40cf 100644 --- a/skills/agent-session-resume/references/cross-platform.md +++ b/skills/agent-session-resume/references/cross-platform.md @@ -18,27 +18,51 @@ Run each platform adapter's discovery independently and completely. Do not let o Keep one candidate list per runtime, each entry carrying session ID, transcript path, cwd, title, and updated time. +## Window the Ask + +Time-bounded asks ("past week", "since Monday", "before yesterday") map to the lister's `--since` / `--until` flags, which accept relative windows (`7d`, `12h`) or ISO dates/datetimes. Pass the same window to every runtime so the merged timeline covers one consistent span: + +```bash +python3 scripts/session-candidates.py --platform claude-code --since 7d --until 1d --format tsv +python3 scripts/session-candidates.py --platform codex --since 7d --until 1d --format tsv +``` + ## Normalize Timestamps -Runtimes mix ISO-8601 strings, local times, and file mtimes. Convert every candidate's time to UTC epoch seconds before comparing across runtimes: +Runtimes mix ISO-8601 strings (often with fractional seconds), local times, and file mtimes. Convert every candidate's time to UTC epoch seconds before comparing across runtimes. Do not reach for BSD `date -j -f`: on real Codex index timestamps such as `2026-06-09T14:03:11.482931Z` it emits "Ignoring 8 extraneous characters" and parses the wrong instant. Use a python3 one-liner that handles fractional-ISO and plain-ISO alike: ```bash -# ISO-8601 -> epoch (BSD date first, GNU date fallback) -date -j -u -f '%Y-%m-%dT%H:%M:%S' '2026-06-09T14:03:11' +%s 2>/dev/null \ - || date -u -d '2026-06-09T14:03:11' +%s +# ISO-8601 (fractional or plain, Z or numeric offset) -> epoch seconds +python3 -c 'import sys,datetime as dt; print(int(dt.datetime.fromisoformat(sys.argv[1].replace("Z","+00:00")).timestamp()))' '2026-06-09T14:03:11.482931Z' # file mtime -> epoch stat -f '%m' "$transcript" 2>/dev/null || stat -c '%Y' "$transcript" ``` +The same one-liner accepts both platforms' lister output: `session-candidates.py` emits `updated_at` normalized to ISO-8601 UTC with seconds precision (e.g. `2026-06-10T00:15:30Z`) for claude-code and codex alike, so lister rows can also be compared or sorted as plain strings. + Never rank candidates from mixed-format timestamp strings. ## Build One Merged Timeline -Merge the per-runtime candidate lists into a single timeline keyed by (cwd match, time window). One TSV line per session, sorted by epoch: +Merge the per-runtime candidate lists into a single timeline keyed by (cwd match, time window). Concretely, with two lister TSVs: + +```bash +python3 scripts/session-candidates.py --platform claude-code --since 7d --format tsv > /tmp/claude.tsv +python3 scripts/session-candidates.py --platform codex --since 7d --format tsv > /tmp/codex.tsv + +# Drop headers, merge, sort chronologically. updated_at (column 3) is normalized +# ISO-8601 UTC on both platforms, so a plain string sort is a time sort. +tail -n +2 /tmp/claude.tsv > /tmp/merged-sessions.tsv +tail -n +2 /tmp/codex.tsv >> /tmp/merged-sessions.tsv +sort -t $'\t' -k3,3 /tmp/merged-sessions.tsv | column -t -s $'\t' +``` + +When iterating rows, never name a loop variable `path`: in zsh, `read ... path` assigns the tied `$path` array and clobbers `$PATH`, breaking every later command lookup in the shell. Use `transcript` (or similar) instead: ```bash -# epoch runtime cwd transcript path title -sort -n /tmp/merged-sessions.tsv | column -t -s $'\t' +while IFS=$'\t' read -r score runtime updated source cwd title transcript; do + printf '%s\t%s\t%s\t%s\n' "$updated" "$runtime" "$cwd" "$transcript" +done < /tmp/merged-sessions.tsv | sort -t $'\t' -k1,1 ``` Group sessions that share a cwd (or parent/child cwd) into per-repo lanes, then read them in time order. The merged timeline decides reading order; the per-runtime adapters decide how to read each transcript safely. diff --git a/tests/trigger-matrix.json b/tests/trigger-matrix.json index 5898f4c..7ea2ce3 100644 --- a/tests/trigger-matrix.json +++ b/tests/trigger-matrix.json @@ -72,6 +72,24 @@ "category": "folder-scoped", "prompt": "Check the last conversation I had with an agent in this folder and tell me where it left off.", "rationale": "Uses folder-scoped last-conversation phrasing and asks for the stopping point." + }, + { + "id": "locate-codex-named-thread", + "category": "locate", + "prompt": "Find Locate Beta driva session thread on Codex", + "rationale": "Asks to locate a named Codex session thread rather than continue work, which is still a session-resume ask." + }, + { + "id": "audit-codex-past-week", + "category": "audit", + "prompt": "review my threads with Codex in the past 1 week and tell me what could have been done better", + "rationale": "Time-windowed audit of prior Codex threads asking for a retrospective review." + }, + { + "id": "cross-platform-claude-codex-review", + "category": "cross-platform", + "prompt": "review all the threads we worked on across both Claude and Codex", + "rationale": "One ask spans Claude and Codex threads, requiring cross-platform discovery and a merged review." } ], "should_not_trigger": [