cristoslc/session-stash-skill · Archived

session-stash

Stash and pop portable agent sessions. A session stash is a durable, git-versioned capture of an in-flight session (normalized transcript + session-relevant uncommitted work + reference files) stored at `docs/session-stash/<name>/`. Stash an active session to resume it later in a different harness (Claude, opencode), a different context window, or a fresh model. Pop a stash to have the resuming agent self-orient from the stash folder's own AGENTS.md. Convert a stash to a sashay, musing, or Jira…

First seen Aug 5, 2026

Installation

$ npx skills add cristoslc/session-stash-skill --skill session-stash

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Declared

Repository health

License MIT
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

LicenseMIT
Compatibilityany-agent
Allowed toolsBash, Read, Write, Edit, Grep, Glob, AskUserQuestion
Declared agents claude-code opencode

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 9,383 B
  • docs SUMMARY.md 782 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 3 installs

SKILL.md

Session Stash

You make in-flight agent sessions portable across harnesses, context windows, and time. A stash captures a session as an encrypted-by-default, git-versioned folder in the project at docs/session-stash/<name>/ (unencrypted only with explicit operator opt-out, confirmed before commit). A pop is the opposite: any agent — in any harness — enters the stash folder and its own AGENTS.md tells it how to resume.

The invariants (MUST NOT violate)

  1. Consumptive pops — popping consumes the stash: it is logically destroyed (leaves the active index, like git stash drop) but never physically deleted. The folder moves to consumed/ and stays readable so the resuming agent can keep referencing its contents. A stash can be popped into only one session.
  2. Encrypted by default; plaintext only with operator sign-off — transcripts are untrustworthy by default. The encrypted-at-rest path is the protocol default. An unencrypted stash is allowed only when the operator explicitly opts out of encryption, and an unencrypted stash MUST NOT be committed until the operator confirms it is intended and secret-free. Only the stash's AGENTS.md is ever scrubbed-plaintext by default.
  3. Light resume is context-only — the disclosure stack is summarized context; all state (patch, file map, git tag) lives in sidecars the resuming agent pulls on demand.
  4. Operator-initiated — you stash only when the operator asks. Never auto-stash.
  5. Fail loud — if a stash is missing, unreadable, un-decryptable, or its AGENTS.md violates the scrubbing contract, STOP and tell the operator. Never silently degrade, coerce, or fall back. Never commit an unencrypted stash without explicit operator confirmation.

When the operator says "stash this session"

  1. Check for an encryption key FIRST — before creating anything, check whether a per-project age key is retrievable (from settings.yaml confirmation, your knowledge of the operator's secrets management, or the secret manager).

- Key exists → proceed to step 1; encryption stays the default path. - No key exists or none is retrievable → STOP and ask the operator NOW, before building the stash: "no age key is available for this project — an unencrypted stash would put the full transcript, patch, and refs in the repo as plaintext." Include a risk-exposure review of what this session's stash would contain: scan your session history for secrets-looking material (API keys, tokens, credentials in tool output, private hostnames/paths, identity-revealing content) and report what would sit plaintext if committed. The operator then chooses: set up a key (encrypt), or proceed unencrypted (which still requires the operator's explicit confirm-before-commit gate in step 7). Never skip this prompt, never infer the answer from silence, and never start capturing the stash before it is resolved.

  1. Create the folder at docs/session-stash/YYYY-MM-DD_HH-MM-<slug>/ (slug = 2-5 word topic).
  2. Build the file map — review your own session history (transcript/tool calls). Identify every file the session touched, read, wrote, or referenced. Do NOT use mtime heuristics (parallel agents share the filespace). Write file-map.md (a sidecar).
  3. Capture the state sidecars:

- git-tag.txt — the commit the session is anchored to (git rev-parse HEAD). - patch.diff — git diff filtered to the file map only (session-relevant uncommitted work, NOT all uncommitted work). - refs/ — reference files (images, logs, artifacts) the session produced or dropped.

  1. Capture the normalized transcript as transcript.md (full session) — harness-agnostic markdown: the story of the session with messages, tool calls, results, decisions. See references/transcript-format.md.
  2. Write the disclosure stack — resume.md (context-only, summarized) plus tiered summary files per references/disclosure-tiers.md. The stack summarizes, never includes verbatim secrets.
  3. Write the stash AGENTS.md — plaintext, scrubbed per references/scrubbing-contract.md. It is the router: it maps context-window tiers to files/line-ranges and tells the resuming agent where the key is.
  4. Encrypt everything except AGENTS.md (default path) — age-encrypt resume.md, transcript.md, file-map.md, git-tag.txt, patch.diff, and refs/ using the project's per-project age key. Confirm key retrieval with the operator on first use per key (see Key retrieval).

- Unencrypted path — if the operator explicitly opts out of encryption (decided at step 0 or later: "stash it unencrypted" / "don't encrypt this one"), skip step 7 but do NOT commit yet. First: (a) scrub resume.md, transcript.md, and refs/ against the scrubbing contract — the same MUST NOT rules apply to any file that will sit plaintext in the repo; (b) ask the operator to confirm: "this stash will be committed unencrypted — confirm it contains no secrets and that's intended." If the operator confirms, mark the stash mode: unencrypted in the index and settings (see references/encryption-and-keys.md); if the operator cannot confirm, STOP — encrypt or drop the stash, never commit an unconfirmed plaintext stash.

  1. Update the index and settings — add the stash to docs/session-stash/README.md (index) and ensure docs/session-stash/settings.yaml records the mode (encrypted or unencrypted), plus the public key + confirmed retrieval source when encrypted.
  2. Commit the stash folder to the project repo.

When the operator says "pop session @docs/session-stash/<name>/"

The pop is not in the skill — it's the stash folder's own AGENTS.md doing the work. The skill's job is to ensure that AGENTS.md is correct and complete so any harness can self-orient. When you or another agent pop:

  1. Read the stash's AGENTS.md first — it routes what to load for your context window.
  2. Pull sidecars (patch, file map, git tag) only as needed.
  3. Decrypt transcript/resume with the referenced key (only for encrypted stashes — unencrypted stashes read directly).
  4. Resume.
  5. Consume the stash — once resumed, move the folder from docs/session-stash/<name>/ to docs/session-stash/consumed/<name>/, drop it from the active index (README.md), and write a consumed.md tombstone inside it recording the pop date and the resumed session's outcome. This is a move, never an rm — the folder stays readable so you (or a future operator) can reference its contents after popping. A pop is single-use: the same stash cannot be popped into two sessions.

Key retrieval

  • Use what you know of the user's secrets management first; confirm that choice with the operator on first use per key.
  • Remember the confirmed source in docs/session-stash/settings.yaml (plaintext, scrubbed — public key + confirmed source only). Subsequent pops for the same key reuse it without re-confirmation.
  • If you cannot determine retrieval, or confirmation is wrong, STOP and fail loudly. Never guess silently.

Conversion

When the operator says "convert stash to ...", the stash closes:

  • → sashay — read the stash, write a fresh plan under docs/plans/ (judgment, not template), then archive the stash to docs/session-stash/backlog/ with a cross-reference. The plan becomes the source of truth.
  • → musing — distill the stash's outcome into a musing under docs/musings/, then archive the stash.
  • → Jira (or other external tracker) — summarize into a ticket, then archive the stash.

Conversion always closes the stash: it moves to backlog/ (archive, never delete).

Off-ramp

When the active stash count exceeds a threshold (default 8, configurable in settings.yaml), surface to the operator the option to move some stashes to backlog/. Never move stashes without operator approval.

Reference documents

  • references/scrubbing-contract.md — what the stash AGENTS.md may/may not contain; the plaintext-safe contract.
  • references/disclosure-tiers.md — the progressive-disclosure stack and per-window line routing.
  • references/transcript-format.md — the normalized, harness-agnostic transcript schema.
  • references/encryption-and-keys.md — age encryption, per-project keys, retrieval confirmation.
  • references/index-and-settings.md — index README + settings.yaml schema.