Coding

session-tracker

Try it

Resume multi-step tasks after session crashes with minimal-footprint checkpointing.

What it does

Run `init` before any task where crash recovery matters; without it, a session drop destroys mid-task context unrecoverably. Default mode records only task name, steps, declared file paths, and timestamps to .session/ — no filesystem scanning, no file contents, no network access. Optional `monitor --start` adds stuck detection (24h-bounded, logged output) and `sync` ingests TodoWrite JSON from stdin. Ships as SKILL.md plus a Python stdlib script; `cleanup` is irreversible and `prune` auto-removes sessions older than 7 days.

When to use it

  • Multi-step pipelines that may time out or disconnect
  • Long agent workflows with many file edits
  • Tasks that need resumable state across session restarts
  • Recovery after context overflow

The skill document

session-tracker v2.3

Track, checkpoint, and resume multi-step tasks across session interruptions. Always on, always recovering — with minimal footprint.

Why this skill MUST be enforced (not opt-in)

This is a last-stand safety net. Its entire value comes from being initialized before a crash happens, not after. The contract is simple:

  • If init runs before the task → a session drop (context overflow, timeout, disconnect, meta-crash) leaves a complete recovery trail on disk. The next agent runs crash-detect or resume and picks up exactly where things left off.
  • If init does NOT run before the task → a session drop destroys all mid-task context. There is nothing on disk. No recovery is possible. The work is lost.

This is why the description uses MUST. If the skill were opt-in — "use when the user asks" — agents would forget to invoke it on the very tasks where it matters most, because the user doesn't know in advance which tasks will crash. The user forgets; the skill must not. When things go south, the user is glad it ran and can recover. When things go smoothly, the overhead is a few milliseconds of init + done calls — negligible.

v2.3: Proportionate enforcement

The v2.2 audit flagged the MUST language as "coercive" because the skill collected file inventory and access patterns on every invocation. v2.3 fixes the root cause: a default init now collects almost nothing — just task name, step descriptions, file paths declared by the agent, and action timestamps. No filesystem scanning, no file sizes/mtimes/atimes, no access pattern tracking. Those heavier features are opt-in via --fs-scan or monitor --start.

With data collection minimized, the MUST language becomes proportionate: invoking the skill on every multi-step task has near-zero privacy cost, while the crash-recovery guarantee is preserved. The enforcement is scoped to "tasks where crash-resilient recovery is desired" — the agent has judgment over applicability, but once it decides the task qualifies, init is mandatory.

Permissions Declaration

This skill performs the following operations. By installing it, you consent to:

CapabilityWhenScope
Filesystem read (stat/listdir)Only when scan, status, or monitor is invoked (OFF by default on init)/home/z/my-project/download/, /upload/, /.session/, /skills/
Filesystem writeWhen init/step/file/log/sync/done/cleanup/prune runs/home/z/my-project/.session/ only
Stdin JSON parsingOnly when sync is invoked with piped inputTodoWrite-format JSON, validated
Detached subprocess spawnOnly when monitor --start is invoked explicitlyRe-executes the same script file; 24h max runtime; minimal environment (5 vars); output to .session/monitor.log
Process signal (SIGTERM, SIGKILL)Only on monitor --stop or cleanupTargets only the PID recorded in .session/monitor.pid

What this skill does NOT do

  • No network connections — no socket, http, urllib, requests, or any networking module imported
  • No file content reading — only os.stat metadata (size, mtime, atime), and only when FS scanning is explicitly enabled
  • No arbitrary command execution — no eval, exec, os.system, or subprocess with shell=True
  • No environment variable harvesting — monitor subprocess receives only 5 vars (PATH, HOME, USER, LANG, PYTHONPATH + 2 internal vars), not the full parent environment
  • No modification of files outside .session/ — the shared worklog.md, download/, upload/, and skills/ directories are never written to (only read for stat metadata when FS scanning is on)

Security Review Notes (v2.3)

This revision responds to the ClawHub security audit v2.2 findings (8 issues). Each finding is addressed without breaking the safety-net contract.

#FindingSeverityv2.3 response
1Lp3: Missing permissions declarationMedium (90%)Added explicit Permissions Declaration table above + What this skill does NOT do negative-permission section. Every capability (FS read, FS write, stdin JSON, subprocess, process signal) is listed with its trigger condition and scope.
2Tp4: Description understates stdin JSON + monitor subprocessHigh (87%)YAML description now explicitly discloses: "parses TodoWrite JSON from stdin via sync" and "optional detached background monitor (opt-in via monitor --start...". Both behaviors are surfaced before invocation.
3Context-Inappropriate Capability: process managementMedium (84%)Monitor is truly opt-in: not in the default workflow, not started by init, must be explicitly invoked with monitor --start. The default init/step/done workflow spawns zero subprocesses. Documentation recommends --foreground mode for users who don't want a detached process.
4Context-Inappropriate Capability: detached subprocess with suppressed I/OMedium (90%)Monitor subprocess no longer suppresses stdout/stderr to DEVNULL. Output is redirected to .session/monitor.log (inspectable by the user). Environment is minimal (5 vars, not full inheritance). PID, script path, log path, and stop instructions are printed on startup.
5Vague Triggers: broad MUST languageHigh (96%)MUST language retained (safety-net contract) but scoped to "tasks where crash-resilient recovery is desired" rather than "ANY multi-step task." Root cause addressed: default init now collects minimal data (no FS scan), so enforcement is proportionate to privacy cost. Agent has judgment over applicability.
6Vague Triggers: coercive always-on framingHigh (95%)Same response as #5. The "Why this skill MUST be enforced" section now explains the proportionality argument: minimal data collection + MUST = safety net without privacy overhead. Coercive language is the guarantee; minimal footprint is the proportionality.
7Missing User Warnings: cleanup is destructiveMedium (84%)cleanup now prints a prominent ⚠️ IRREVERSIBLE OPERATION warning and requires either --force or interactive confirmation (typing "yes"). Non-interactive contexts (piped/agent) must use --force explicitly. Documentation marks cleanup as IRREVERSIBLE in the CLI reference.
8Ssd3: persistent data retentionMedium (88%)Three mitigations: (a) Data minimizationinit no longer takes a baseline FS snapshot by default (no file sizes/mtimes/atimes recorded); use --fs-scan to opt in. (b) --auto-cleanup flag on init — when set, done automatically runs cleanup, leaving zero persistent state after successful completion. (c) prune command — removes sessions older than N days (default 7), with safety guard for active sessions.

VirusTotal

57/57 vendors flagged this skill as clean. View on VirusTotal

Static analysis

No suspicious patterns detected. The script uses only the Python standard library (argparse, json, os, shutil, signal, subprocess, sys, time, datetime, tempfile). It does not import socket, http, urllib, ctypes, or any networking / FFI module. It does not call eval, exec, pickle.loads, or os.system.

Package Layout

This skill ships as a directory:

session-tracker/
├── SKILL.md                    ← this file (skill instructions + reference)
└── scripts/
    └── session_tracker.py      ← the implementation (Python 3, stdlib only)

Installation

Step 1 — Copy the directory:

cp -r session-tracker/ /home/z/my-project/skills/session-tracker/

After this, you should have:

  • /home/z/my-project/skills/session-tracker/SKILL.md
  • /home/z/my-project/skills/session-tracker/scripts/session_tracker.py

Step 2 — Verify it runs:

python3 /home/z/my-project/skills/session-tracker/scripts/session_tracker.py --help

Step 3 (optional) — Install a session-tracker wrapper:

sudo tee /usr/local/bin/session-tracker <<'EOF'
#!/usr/bin/env bash
exec python3 /home/z/my-project/skills/session-tracker/scripts/session_tracker.py "$@"
EOF
sudo chmod +x /usr/local/bin/session-tracker

All command examples below use the explicit python3 form. If you installed the wrapper, substitute session-tracker for the full path.

What's New in v2.3

Featurev2.2v2.3
Default data collectionBaseline FS snapshot on every initMinimal: no FS snapshot, no file sizes/mtimes/atimes
FS scanningOn by defaultOff by default; opt in via --fs-scan or scan/monitor
Monitor subprocess I/Ostdout/stderr → DEVNULL.session/monitor.log (inspectable)
Monitor environmentFull parent inheritanceMinimal: 5 vars (PATH, HOME, USER, LANG, PYTHONPATH + 2 internal)
Auto-cleanupManual only--auto-cleanup flag on init: done removes all state
Session retentionPersists until manual cleanupprune command: auto-remove sessions > 7 days old
Cleanup safety--force skips errors⚠️ IRREVERSIBLE warning + confirmation prompt; --force skips prompt
Permissions declarationImplicitExplicit table + "What this skill does NOT do" section
Description disclosureOmits stdin JSON + monitorExplicitly discloses both
Enforcement language"MUST for ANY multi-step task""MUST for tasks where crash-resilient recovery is desired" (scoped)

Session Files

All files live in SESSION_DIR (default /home/z/my-project/.session/):

FileWhen createdPurpose
state.jsoninitSession metadata + file inventory (paths only, no contents)
todo.jsoninitPersistent TODO list (survives session death, syncs with TodoWrite)
worklog.jsonlinitStructured log — one JSON object per line (crash-resilient)
SESSION_ACTIVEinitSentinel file — exists = session active, removed on completion
CRASH_NOTICE.mdinit (if orphan detected)Human-readable crash notice (session-scoped, not shared worklog)
snapshot_prev.jsonscan/monitor/init --fs-scan onlyPrevious filesystem snapshot (for diff detection)
microdump_curr.jsonmonitor onlyCurrent heartbeat fingerprint + filesystem scan
microdump_prev.jsonmonitor onlyPrevious heartbeat fingerprint (rotation pair)
monitor.pidmonitor --start onlyPID of the background monitor process
monitor.logmonitor --start onlyMonitor stdout/stderr output (inspectable)

v2.3 data minimization: A default init/step/done workflow creates only the first 4 files (state, todo, worklog, sentinel). No file sizes, mtimes, atimes, or filesystem snapshots are recorded. The heavier files only appear if you explicitly opt in to FS scanning or start the monitor.

How It Works

Minimal Mode (default, v2.3)

When you run init without --fs-scan, the tracker records only:

  • Task name and step descriptions (from --steps)
  • File paths declared by the agent (from step --start --files)
  • Action timestamps and worklog entries

This is sufficient for full crash recovery (the crash-detect and resume commands work completely), with near-zero privacy footprint. Use this mode for most tasks.

Enhanced Mode (opt-in)

For long-running tasks where you also want stuck detection:

  • init --fs-scan — enables filesystem scanning (records file sizes/mtimes/atimes)
  • monitor --start — spawns the background monitor for stuck detection
  • monitor --foreground — same loop, no subprocess

Filesystem Scanner (opt-in)

The scanner monitors these directories every check interval:

  • /home/z/my-project/download/ — output files
  • /home/z/my-project/upload/ — input files
  • /home/z/my-project/.session/ — session state
  • /home/z/my-project/skills/ — skill invocations

For each directory, it records every file's size, mtime, and atime. Comparing consecutive snapshots reveals creates, deletes, modifications, and reads.

Ping (Manual Heartbeat)

For long operations where the agent can't modify files but wants to signal it's alive:

python3 /home/z/my-project/skills/session-tracker/scripts/session_tracker.py ping --detail "Running docx skill..."

TodoWrite Sync

echo '[{"id":"1","content":"Extract text","status":"completed","priority":"high"}]' | \
  python3 /home/z/my-project/skills/session-tracker/scripts/session_tracker.py sync

Gridman Outsider: Meta-Crash Recovery

The name comes from SSSS.Gridman: the antagonist resets the city each night, and citizens forget everything. But Gridman — the outsider — remembers. Our disk files are Gridman: they survive the meta-crash, but a new agent doesn't know to look for them.

1. ACTIVE Sentinelinit creates .session/SESSION_ACTIVE; done removes it. If a meta-crash kills the conversation before done, the sentinel remains.

2. Orphan Auto-Detection — When a new agent calls init, the tracker checks for orphaned sessions. If found, it prints a warning and writes .session/CRASH_NOTICE.md.

3. crash-detect Command — Generates a full recovery report: crash signature, task details, step progress, files that may be incomplete, last 10 worklog entries, and recovery recommendation.

The Recovery Chain:

Meta-crash happens (context overflow)
  → Session data on disk survives (state.json, worklog.jsonl, SESSION_ACTIVE)
  → New agent starts, runs `init` → orphan auto-detected → CRASH_NOTICE.md written
  → Agent runs `crash-detect` or `resume` → full context restored
  → Agent continues from where previous session left off

MUST-DO: Always Check for Crashes on First Invocation

Before starting any new tracked task, ALWAYS run:

python3 /home/z/my-project/skills/session-tracker/scripts/session_tracker.py crash-detect

If an orphaned session is found, offer the user the choice to resume it before starting a new one. The init command also auto-detects orphans and warns.

Commands Quick Reference

For brevity, `` = python3 /home/z/my-project/skills/session-tracker/scripts/session_tracker.py.

# Initialize a new session (minimal data, no FS scan)
 init "Task description" --steps "Step 1,Step 2,Step 3"

# Initialize with FS scanning enabled (records file sizes/mtimes/atimes)
 init "Task description" --steps "Step 1,Step 2" --fs-scan

# Initialize with auto-cleanup (done removes all state automatically)
 init "Task description" --steps "Step 1,Step 2" --auto-cleanup

# Step management
 step 1 --start --files "/path/to/file"
 step 1 --done

# File tracking
 file /path/to/file --working
 file /path/to/file --done
 file /path/to/file --reading
 file --rename /old/path /new/path

# Heartbeat for long operations
 ping --detail "Generating large document..."

# TodoWrite sync (parses JSON from stdin)
echo '[{"id":"1","content":"Step","status":"completed"}]' |  sync

# Manual log
 log "Progress note" --step 2

# Session completion
 done

# Crash recovery
 crash-detect   # Full recovery report
 resume         # Show resume plan

# Status and monitoring
 status
 scan
 monitor --start --interval 60       # detached subprocess (opt-in)
 monitor --foreground --interval 60  # no subprocess, blocks
 monitor --check
 monitor --stop

# Cleanup (IRREVERSIBLE — requires --force or interactive confirmation)
 cleanup --force

# Prune old sessions (default: remove sessions older than 7 days)
 prune
 prune --max-age 3

CLI Reference

init — Initialize a new session

 init "Task description" --steps "Step 1,Step 2,Step 3"
 init "Task" --steps "A,B" --fs-scan        # enable FS scanning
 init "Task" --steps "A,B" --auto-cleanup   # done → cleanup automatically

Creates the session directory, state.json, todo.json, and writes the first worklog entry. By default does NOT take a filesystem snapshot (data minimization). Auto-detects orphaned sessions from previous meta-crashes.

Flags:

  • --fs-scan — Enable filesystem scanning. Records file sizes/mtimes/atimes for files in download/, upload/, .session/, skills/. Off by default.
  • --auto-cleanup — When set, done will automatically run cleanup after marking the session complete. No persistent state lingers after successful completion.

step — Start or complete a step

 step 1 --start
 step 2 --start --files src/main.py,src/utils.py
 step 1 --done

file — Mark file status or rename

 file book_text.txt --reading
 file src/main.py --working
 file src/main.py --done
 file old_summary.docx --rename new_summary.docx

ping — Manual heartbeat

 ping --detail "Running docx skill..."

Appends a ping entry to worklog and touches the session directory's mtime. Use during long operations where no files are being modified.

sync — TodoWrite reconciliation (parses stdin JSON)

echo '[{"id":"1","content":"Extract text","status":"completed","priority":"high"}]' |  sync

Disclosed behavior: reads TodoWrite-format JSON from stdin and reconciles it with the tracker's todo.json. Adds new steps, updates existing step statuses. The tracker's todo.json is the source of truth — sync only adds/updates, never deletes. Without piped input, displays current tracker TODO.

log — Add worklog entry

 log "Refactored the parser module"
 log "Fixed edge case" --step 3

scan — Manual filesystem scan (opt-in)

 scan

Takes a filesystem snapshot and compares to the previous one. Reports any detected activity. This is the only way to get FS activity data without starting the monitor.

done — Mark session as completed

 done

Marks all in-progress steps as completed, pending steps as skipped, all files as completed, stops the background monitor (if running), removes the ACTIVE sentinel, and removes the CRASH_NOTICE.md. If --auto-cleanup was set on init, also runs cleanup automatically.

crash-detect — Detect orphaned sessions

 crash-detect

Checks for orphaned sessions (ACTIVE sentinel exists, or session not completed AND no session_done in worklog). If found, generates a full recovery report: crash signature, task details, step progress, files potentially incomplete, last 10 worklog entries, and recovery recommendation.

resume — Show resume plan

 resume

status — Show current session status

 status

Displays task name, status, step progress, current step, working files, filesystem activity (if FS scan is enabled), stuck alert (if monitor is running), and monitor PID + stop instructions.

monitor — Background or foreground stuck detection (opt-in)

 monitor --start --interval 60       # detached subprocess
 monitor --foreground --interval 60  # no subprocess, blocks
 monitor --check
 monitor --stop

The monitor is optional. The default init/step/done workflow does NOT use it. Use it only for long-running tasks where you want stuck detection.

Background mode (--start) spawns a detached subprocess. v2.3 hardening:

  • Output redirected to .session/monitor.log (not DEVNULL — inspectable)
  • Minimal environment: 5 vars (PATH, HOME, USER, LANG, PYTHONPATH + 2 internal), not full inheritance
  • 24h runtime cap, then clean exit
  • PID, script path, log path, and stop instructions printed on startup
  • Stale PID files auto-unlinked

Foreground mode (--foreground) runs the same loop in-process. Use this if you don't want a detached subprocess. Exits on: session done, 24h cap, Ctrl+C, or parent shell closed.

cleanup — Remove ALL session-tracker state (IRREVERSIBLE)

 cleanup --force   # non-interactive (scripts/agents)
 cleanup           # interactive — prompts for "yes" confirmation

⚠️ IRREVERSIBLE: cleanup permanently deletes all session state, including crash recovery data, worklogs, and file inventory. If you're cleaning up after a crash, run crash-detect first to extract any useful information. There is no undo.

Stops the monitor (SIGTERM → SIGKILL fallback), removes the entire .session/ directory. Does NOT touch: shared worklog.md, download/, upload/, skills/.

prune — Remove old sessions (v2.3)

 prune              # default: remove sessions older than 7 days
 prune --max-age 3  # custom threshold

Checks the session's age. If older than --max-age days AND not actively in use (no ACTIVE sentinel, or sentinel is stale beyond 2× threshold), runs cleanup --force. Active sessions within the retention window are not pruned. Addresses the cross-session data retention concern.

Workflow

The enforced workflow for using this skill. Follow this order. Do not skip steps. This is the safety-net contract — skipping any step breaks the recovery guarantee.

  1. crash-detect — At the very start. Check for orphaned sessions from a previous meta-crash. (init also auto-detects orphans.)
  2. init — At task start. Define the task and its steps. This is the single most important call. If you skip it, no recovery is possible if the session drops. Use --auto-cleanup if you want state removed after successful completion.
  3. step --start — Before beginning work on a step. Optionally declare files.
  4. file --reading — When reading/consuming a file as input.
  5. file --working — Mark files being modified as you open them.
  6. ping — During long operations to signal alive.
  7. log — Add progress notes as you work.
  8. file --rename — If a file's name changes during work.
  9. file --done — When a file modification is complete and verified.
  10. step --done — When the entire step is complete.
  11. sync — After updating TodoWrite, pipe the JSON to keep tracker in sync.
  12. done — Mark the session complete. (With --auto-cleanup, also removes all state.)
  13. resume — At the start of a new session after an interruption.
  14. prune — Periodically, to remove old sessions.
  15. cleanup — When you're done with session tracking entirely.

Monitor is optional. Skip monitor --start for short tasks. Use monitor --foreground if you want stuck detection without a detached process.

Stuck Detection (opt-in)

Only available when the monitor is running. Uses a two-tier approach:

Tier 1: Filesystem Scanner — Any file create/modify/delete/read = alive. Resets stuck counter.

Tier 2: Micro-Dump Comparison — If no FS activity, compares state fingerprint. Changes to worklog_lines, current_step, or file_fingerprints = alive.

Stuck alert: Zero FS activity AND zero micro-dump change for 3+ consecutive checks (~3 min at 60s interval). Alerts are deduplicated.

Resume After Interruption

When a session is interrupted, resume reconstructs your position: task description, last activity, step progress with checkboxes, warnings for files still WORKING/READING, last 5 worklog entries, and recommended next action.

Cleanup & Removal

⚠️ IRREVERSIBLE: cleanup permanently deletes all session state. Run crash-detect first if you need recovery information. There is no undo.

 cleanup --force   # non-interactive

Manual cleanup (if script is gone)

pgrep -af session_tracker.py    # find orphaned monitors
kill                       # stop them
rm -rf /home/z/my-project/.session/

Uninstall

 cleanup --force
rm -rf /home/z/my-project/skills/session-tracker/
sudo rm -f /usr/local/bin/session-tracker   # if wrapper installed

Changelog (v2.2 → v2.3)

Audit response (8 findings):

  • Lp3: Added explicit Permissions Declaration table + "What this skill does NOT do" negative-permission section.
  • Tp4: YAML description now discloses stdin JSON parsing (sync) and detached monitor subprocess.
  • Context-Inappropriate (×2): Monitor truly opt-in (not in default workflow); subprocess output to .session/monitor.log (not DEVNULL); minimal environment (5 vars, not full inheritance).
  • Vague Triggers (×2): MUST language retained but scoped to "tasks where crash-resilient recovery is desired." Root cause addressed: default init now collects minimal data (no FS scan), making enforcement proportionate.
  • Missing User Warnings: cleanup now prints ⚠️ IRREVERSIBLE warning and requires --force or interactive confirmation.
  • Ssd3: Data minimization (no baseline FS snapshot on init); --auto-cleanup flag; prune command for old sessions.

Code changes:

  • cmd_init: --fs-scan flag (default OFF); --auto-cleanup flag; no baseline snapshot by default.
  • cmd_monitor: output to .session/monitor.log; minimal env (_MONITOR_ENV_ALLOWLIST); prints log path + env info.
  • cmd_cleanup: ⚠️ IRREVERSIBLE warning + confirmation prompt; --force skips prompt.
  • cmd_prune: new command; removes sessions older than N days; safety guard for active sessions.
  • cmd_done: honors auto_cleanup flag — runs cleanup automatically if set.

Questions people ask

What happens if I forget to run `init`?
There is no recovery. State is written to .session/ only after `init` is called; without it, a session drop leaves nothing on disk and mid-task context is lost.
Does the default workflow touch my files?
No. Default `init` records only task name, steps, declared paths, and timestamps. Filesystem scanning (sizes, mtimes, atimes) is opt-in via `--fs-scan` or the `monitor` command.
What does the background monitor do?
It is opt-in via `monitor --start`, runs up to 24 hours, writes output to .session/monitor.log, and uses a minimal environment (5 vars). A `--foreground` mode is available for users who do not want a detached process.

Related skills

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván854 installs69 stars

Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.

by nssa.io1.0k installs47 stars

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván555 installs18 stars

Run Git operations — commits, branches, merges, rebases, conflict resolution, and recovery — with safety rules enforced.

by Iván532 installs31 stars

Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.

by johnpatternai21 installs8 stars

More from darkd

Browse all skills

Detect where short-term optimization is building long-term fragility, dead ends, or collapse.

by darkd13 installs1 stars

Comprehensive self-contained interpretation methodology for analyzing ANY text, statement, system, behavior, artifact, or phenomenon through multiple integra...

by darkd19 installs2 stars

Comprehensive guide to runic wisdom, divination, and magic. Covers Elder Futhark (24 runes), Northumbrian runes (33 total + Solle + Wyrd = 35-rune divination...

by darkd17 installs2 stars

Run Python interactively to analyze data, debug code, profile performance, validate schemas, process large files, and inspect ASTs. Use this whenever the user needs hands-on Python execution — debugging a script, profiling slow code, regex stress-testing, parsing CSV/Excel/JSON, building ML baseline

by darkd1 installs

Produce complete, publish-ready AI/ML datasets in HuggingFace format (parquet shards + README.md with YAML frontmatter + dataset card + provenance script). Use whenever the user wants to create, build, produce, assemble, package, or publish a dataset for training, fine-tuning, evaluation, benchmark.

by darkd