mcpField
T
track-session

track-session

github.com/antjanusAgent workflows286 installsUpdated 1w ago
Repository

About track-session

track-session is a skill for keeping multi-session project work resumable through a root-level SESSION_PROGRESS.md file. It defines checkpoint, save, resume, verification, and recovery workflows, with a format consumed by the cc-dash dashboard.

Key features

  1. 01Maintain a structured session progress file
  2. 02Checkpoint changes, failures, and decisions
  3. 03Resume from recorded status and next steps
  4. 04Verify completed tasks with evidence
  5. 05Recover a deleted file from a transcript

Use cases

  1. 01Pause work and continue in a later session
  2. 02Record decisions and failed approaches for handoff
  3. 03Verify that marked tasks are complete
  4. 04Restore session progress after file deletion

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/antjanus/skillbox --skill track-session

After installing, type/track-sessionin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

reference/
EVAL.md
RECOVERY.md
TROUBLESHOOTING.md
VERIFICATION.md

Details

From the project README

Session Progress

Overview

Track multi-session work in SESSION_PROGRESS.md at the project root so work can pause and resume without a context rebuild. The file is only worth having if it matches reality, so checkpoint as work happens — after a completed task, a plan change, a failure, or before asking the user a question — rather than waiting to be told to save.

The cc-dash dashboard ingests this file, which is why the frontmatter schema and the HTML id markers below are load-bearing rather than decorative.

File format

---
schema: cc-dash/session@1
project: project-name
session_id: s_YYYY-MM-DD_topic-slug
roadmap_ref: r_XXXXX          # optional — links a roadmap feature
started: YYYY-MM-DDTHH:MM:SS-TZ
last_updated: YYYY-MM-DDTHH:MM:SS-TZ
status: in-progress           # in-progress | paused | completed | blocked
---

# Session Progress

## Bench note

- **Did:** <what got finished, in plain words>
- **Next:** <what happens next, in plain words>
- **Needs you:** <a question or decision waiting on the user; drop the line if none>
- **Acted on:** n_ab12c, <a few words on what was done; only when a note id was given>

## Plan

- [ ] <!-- id:t_a1b2c dep:none --> Task: description
- [x] <!-- id:t_d3e4f dep:t_a1b2c --> Task: description

## Current Status

Working on: <current task>
Next: <specific next action — name files and functions, not "fix the bug">

## Decisions

- <!-- at:YYYY-MM-DDTHH:MM:SS-TZ --> Durable choice + why, so it isn't relitigated on resume

## Failed Attempts

- <!-- id:f_x1y2z task:t_d3e4f --> Tried X: failed because Y, trying Z instead

## Completed Work

- <!-- ref:t_d3e4f at:YYYY-MM-DDTHH:MM:SS-TZ --> What was done

## Plan and ## Current Status are load-bearing; ## Bench note is expected, and ## Decisions, ## Failed Attempts, and ## Completed Work are optional — add them when there's something real to record.

Bench note

The Bench note is a short status for the person running the agents, written the way you'd tell a colleague where things stand. It has no task ids, no file paths and no jargon the reader would have to look up; that detail belongs in ## Current Status, which is written for the next agent. cc-dash reads it from its heading, wherever it sits in the file.

  • Did and Next: one sentence each.
  • Needs you: a question or decision that is waiting on the user. Leave the line out when nothing is.
  • Acted on: when the user's prompt or a note carries an id like n_ab12c, record it once you have acted on it: the id, a comma, then a few words on what you did. One line per note. Write it only for ids you were given and have acted on, because cc-dash takes the line as proof and never guesses.

Rewrite the section, don't append to it, at every checkpoint and save and before you end the session or stop to ask the user something. Carry earlier Acted on lines forward within the session. Keep it to about four lines, each a sentence; a note that needs scrolling is a second Current Status.

Length: one line per task; Decisions and Failed Attempts get 1–2 sentences each. The file is a state record, not a narrative — no filler sections, no restated summaries, no recap of work already listed under Completed Work.

What must survive a context reset, in priority order: problems that came up and how they were resolved (Failed Attempts); options raised, tried, or set aside, and why (Decisions); anything the user asked for, ruled out, or set as a constraint, stated close to their own words; exactly where things stand (Current Status); what is still open or promised (Plan); and details that are hard to reconstruct — names, numbers, exact wording, links — kept exact. Be complete on these even at the cost of length. Condense your own reasoning to what it concluded.

IDs: t_ (task) or f_ (failed attempt) plus 1–20 [a-z0-9_-] chars — five random chars by default, or a mnemonic slug (t_redis-mw, t_authfix). The same shape applies to task: and ref:, which each take exactly one id. roadmap_ref takes exactly one roadmap id; when a session advances several features, name the others under ## Current Status. Keep an id stable once written, because dep: references point at it. Every plan item carries an id and a dep (dep:none or dep:t_XXXXX).

Log every failed approach with its reason so it isn't blindly retried. When a failure was environment-scoped — an MCP server not connected, missing credentials, a service down — say so in the entry; a later session may have a different environment, so re-checking it is correct rather than a repeat.

Workflow

Routing a bare invocation

On /track-session with no argument, take the first branch that matches and stop:

  1. No SESSION_PROGRESS.md at the project root → Start. Don't rebuild one from the roadmap or git history; that is recover, and only on request.
  2. File exists and this conversation has produced work the file doesn't record yet (edits, test runs, decisions since its last_updated) → checkpoint, then keep working.
  3. File is status: completed → say the last session closed and what it finished, then hand off to /track-roadmap resume to pick the next feature, or to Start if the user already named the new work.
  4. Otherwise — fresh context, the file is the only record → Resume.

The discriminator is unrecorded work in the current conversation, not how finished the file looks. Use it as a tiebreak whenever branches 2 and 4 both seem to fit: checkpoint. Writing a near-empty delta costs one turn, whereas resuming on top of unrecorded work drops it from the file and hands the next session a stale plan.

Start mode

Derive project: from the repo (folder name, package.json, pyproject.toml) rather than inheriting it from a file you're about to overwrite. Stamp started and last_updated from the clock (see Checkpoint), set status: in-progress, and write at least ## Plan, ## Current Status and ## Bench note.

If a SESSION_PROGRESS.md already exists, read it, then check whether git tracks it — that determines whether replacing it is reversible:

git ls-files --error-unmatch SESSION_PROGRESS.md   # exit 0 = tracked; non-zero = untracked or ignored
  • Same work, unfinished → this isn't Start, it's Resume. Stop here.
  • Tracked, and the prior session is completed/paused and unrelated → confirm with the user, then replace the file; git holds the old copy.
  • Untracked or gitignored → archive to SESSION_ARCHIVE_<topic>.md first, then write the clean file. Replacing an untracked file destroys it permanently; public repos commonly gitignore SESSION_PROGRESS.md on purpose. When they do, offer to add SESSION_ARCHIVE_*.md to .gitignore too, so the archive doesn't become the thing that leaks.
Checkpoint (bare invocation) and Save

Both write the current state into the file: tick completed tasks, update ## Current Status, rewrite ## Bench note, append decisions and failed attempts, re-stamp last_updated. The only difference is what happens next — a bare /track-session checkpoints and keeps working, while /track-session save checkpoints and stops.

Take every timestamp from the clock rather than estimating it, because a guessed stamp drifts by hours and the dashboard's staleness view trusts it:

date +%Y-%m-%dT%H:%M:%S%z | sed -E 's/([0-9]{2})$/:\1/'   # 2026-09-22T11:19:48-06:00

When the last plan task is ticked, set status: completed in the same write and tell the user the session is closed. A finished file left in-progress shows as active work on the dashboard indefinitely.

Resume mode

Read the file, then lead the reply with where things actually stand — status, tasks done out of total, working-tree state, last commit, and the next action — before any fresh analysis. Handoffs that open with narration ("I'll read the session file now, then look at the tests") bury the state the user came back for, and they end up re-deriving it themselves.

Resume is also the natural reconciliation point: if project: or status: have drifted from reality, fix them in place while you're there.

Verify and Recover — load on demand
  • /track-session verify confirms [x] tasks actually meet their requirements — read the files, run the tests, tie each claim to evidence from this run, and append a ## Verification Results section, which cc-dash renders on the session page. Load reference/VERIFICATION.md when the user asks to verify, or when ticked boxes are the only evidence the work is done.
  • /track-session recover rebuilds a deleted SESSION_PROGRESS.md from the Claude Code transcript. Load reference/RECOVERY.md when the file is missing and the user wants it back — it carries the transcript-slug derivation and a tested Python reconstructor, which the reference explains is necessary because jq mis-parses these transcripts.

Examples

✅ Specific and resumable:

## Plan
- [x] <!-- id:t_a1b2c dep:none --> Phase 1: choose session store (picked Redis)
- [ ] <!-- id:t_g5h6i dep:t_a1b2c --> Phase 2: add session middleware

## Current Status
Working on: Phase 2
Next: add Redis client in src/auth/session.ts, then wire middleware in app.ts

❌ Too vague to resume:

## Plan
- [ ] Do auth stuff
- [ ] Fix sessions
Working on auth. Tried some things that didn't work.

✅ A resume reply that opens with state:

Paused, 4 of 7 plan tasks done, working tree clean, last commit 3cf23e0 "add session middleware".
Next: add the Redis client in src/auth/session.ts, then wire it in app.ts.

❌ A resume reply that opens with narration:

Let me start by reading your SESSION_PROGRESS.md to understand the context.
Then I'll check the git log and look through the auth directory...

✅ A failed attempt that won't be blindly retried:

## Failed Attempts
- <!-- id:f_k7m2p task:t_g5h6i --> Tried `ioredis` autoReconnect for the session store: reconnect storms under the test harness's socket limit. Switched to a single shared client in src/auth/redisClient.ts.
- <!-- id:f_q9r4s task:t_g5h6i --> Ran the e2e suite against staging: env-scoped — STAGING_URL unset in this shell. Re-check before treating this as a real failure.

❌ A failed attempt that will be retried:

## Failed Attempts
- Redis didn't work, trying something else

✅ A Bench note the user can read in ten seconds:

## Bench note

- **Did:** Landed the forest and sand vistas.
- **Next:** Town vistas, then stop for review.
- **Needs you:** Dusk or noon light for the town?
- **Acted on:** n_ab12c, stopped after sand as asked.

❌ A Bench note written for the agent, or one that can't be matched:

## Bench note

- **Did:** t_a1b2c done, patched src/scene/vista.ts L40-88, tests green
- **Acted on:** stopped after sand as asked

✅ Every good version names the file, the id, and the reason; every weak one makes the reader rebuild context from scratch.

Gotchas

  • Only the top frontmatter block is parsed. Anything below a second --- is invisible to cc-dash, so a file with stacked sessions silently reports only the newest one.
  • SESSION_PROGRESS.md is gitignored in many public repos, which makes "just replace it, git has the history" false there. Check git ls-files --error-unmatch before replacing, and archive first when it comes back non-zero.
  • cc-dash drops an entry whose id doesn't match, with a warning, and keeps the rest. A comma list in ref: or roadmap_ref, or an id with a space or capital, loses that one entry or link from the dashboard. Fix the malformed value, but don't rewrite valid mnemonic ids into random tokens — renaming an id orphans every dep: pointing at it.
  • Re-stamp last_updated on every write. The dashboard's staleness view keys off it, so a checkpoint that skips the stamp makes active work look abandoned.
  • save stops work. Users who type it mid-flow expecting a checkpoint then wonder why you halted; a bare /track-session is the one that checkpoints and continues.
  • save with subagents still running doesn't stop them. Their results arrive after you've said you stopped. Name each in-flight agent and what it's doing under ## Current Status, and tell the user results will still land, so the next session knows to look for them.
  • A Bench note line cc-dash can't read is dropped with a warning; the rest still counts. Keep the labels exact (Did, Next, Needs you, Acted on) and start every Acted on with a lowercase n_ id of five characters. Two Bench note sections mean only the first is read, so rewrite in place.
  • Other headings are kept but not shown. cc-dash reads Plan, Current Status, Bench note, Decisions, Failed Attempts and Completed Work, and displays Verification Results; a ## Notes section survives on disk but never reaches the dashboard. Put a finding that should outlive the session on the linked roadmap item as a quoted note (see track-roadmap) rather than in an invented section.
  • One file per repo, at the root. Work in a subdirectory (a godot/ or web/ folder) still checkpoints to the root file; a second SESSION_PROGRESS.md deeper in the tree splits the record and the dashboard reads only one.
  • Write the file with Edit or Write, not a Bash heredoc or sed -i. recover rebuilds the file by replaying Edit and Write calls from the transcript, so an update made through Bash is invisible to it.
  • Recovery rarely finds a clean blob. Because updates are incremental Edits, the transcript usually holds no full Write — expect to replay edits over the latest snapshot rather than lifting one copy out.

Integration

  • track-roadmap — pick a feature from the roadmap, then link its implementation here via roadmap_ref: r_XXXXX. Research, open questions and rejected alternatives that matter beyond this session go back to that roadmap item as quoted notes before the session closes.
  • Checkpoint between commits and test phases, so the file's state lines up with a commit boundary a later session can git show.

See reference/TROUBLESHOOTING.md for resume failures, oversized session files, and verify edge cases.

Comments

Markdown supported