Session Memory
Manage session memory artifacts in repos that have opted in via a docs/agent-sessions/ directory.
Two modes: start creates the session directory with a template memory.md; finalize checks for
completeness and stages everything.
Use a layered memory model (influenced by OpenClaw):
- Session artifact (source of truth for one run):
docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/memory.md
- Working memory log (append-only timeline):
docs/agent-sessions/memory/YYYY-MM-DD.md
- Durable memory (curated cross-session memory):
docs/agent-sessions/MEMORY.md
Session directories still prevent collisions across parallel worktrees, while the log and durable
files make recall easier across many sessions.
Memory Rules
- Never claim memory persistence unless it is written to disk in this repo.
- If the user says "remember", "note this", "save this", or equivalent, write it to the current
session
memory.md and clearly mark it if it is durable (decision, preference, stable fact,
recurring pitfall) so it can be promoted later.
- Use
docs/agent-sessions/memory/YYYY-MM-DD.md for operational breadcrumbs and chronology during
the run; do not curate heavily there.
- Update
docs/agent-sessions/MEMORY.md during finalize by promoting durable items from the
session artifact. Keep entries short, deduplicated, and date-stamped.
Prerequisites
- You must be working inside a repo that has a
docs/agent-sessions/ directory.
- You must be on a feature branch (not
main/master).
- You must not be on detached HEAD (
git branch --show-current must be non-empty).
Detecting Context
Before either mode, determine:
Session name: Extract from $PWD. If the path contains .claude/worktrees/<name>/ or
.codex/worktrees/<name>/, use
<name>. Otherwise, use the branch slug (branch name after the last /, e.g.,
user/add-oauth → add-oauth).
Repo root: Run git rev-parse --show-toplevel.
Branch: Run git branch --show-current.
Scope: Derive from issue number, PR number, or branch name (in priority order):
- If the PR body contains
Closes #N or Resolves #N, use issue-{N}.
- If a PR exists for the current branch (
gh pr view --json number,body --jq .), use pr-{N}.
- If the branch name contains an issue reference (e.g., created by
/pick-up-issue), extract the
issue keyword and use issue-{N} or the slug as scope.
- Otherwise, take the branch slug after the
/ (e.g., bkonkle/add-oauth → add-oauth).
Date: Today's date as YYYY-MM-DD.
Session directory: docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/.
Session ID: Parse from the agent JSONL transcript path. Prefer the structured
session_meta.payload.id value from the transcript, and include Codex archived transcripts as a
fallback source.
Use this detection order:
a. Build candidate transcript list from:
find ~/.codex/sessions -type f -name '*.jsonl' 2>/dev/null
find ~/.codex/archived_sessions -maxdepth 1 -type f -name '*.jsonl' 2>/dev/null
find ~/.claude/projects -type f -name '*.jsonl' 2>/dev/null
b. Prefer the most recent candidate whose session_meta.payload.cwd contains the current repo
root path (or current worktree path).
c. Extract the session ID:
- First choice:
jq -r 'select(.type=="session_meta" and .payload.id != null and .payload.id != "") | .payload.id' <file> | head -1
- If missing, parse UUID from filename with:
grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
- If still missing and filename starts with
rollout-, use the rollout filename stem (without
.jsonl) as a temporary Session ID and note it is rollout-formatted.
d. If no candidate matches, leave as (unknown) and note the user can fill it manually.
If docs/agent-sessions/ does not exist in the repo root, stop and tell the user the repo has not
opted in. They can opt in by creating docs/agent-sessions/README.md.
Shell Portability
- Prefer POSIX-compatible shell snippets in this skill (
sh/zsh safe).
- If you need bash-only builtins (
mapfile, read -a), explicitly run commands through
/bin/bash to avoid zsh failures.
Mode: start
Parse $ARGUMENTS — if it equals start (or is empty), run this mode.
Steps
Check for existing session directory. If docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/
already exists, print its path and note that it's ready for use. Do not overwrite.
Create the session directory:
mkdir -p docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}
Create memory.md with this template (fill in known fields, leave placeholders for others):
# Memory: <title — describe the work>
| Field | Value |
| ---------- | ------------------ |
| Session | {session-name} |
| Date | YYYY-MM-DD |
| Session ID | {sessionId} |
| PR | (pending) |
| Branch | {branch} |
| Issue(s) | (none yet) |
## Goal
<!-- What this session sets out to accomplish -->
## Key Decisions
<!-- 1. **Decision** — Rationale. Alternatives considered. -->
## Approach
<!-- Implementation strategy, files changed, patterns followed -->
## Problems Encountered
<!-- - **Problem** — Root cause and fix -->
## Outcome
<!-- End state: merged, open for review, follow-up needed -->
## Follow-ups
<!-- - [ ] Unresolved items for future sessions -->
Ensure layered memory files exist:
mkdir -p docs/agent-sessions/memory
touch "docs/agent-sessions/memory/YYYY-MM-DD.md"
If docs/agent-sessions/MEMORY.md does not exist, create it with:
# Durable Memory
## Decisions
<!-- Stable decisions that future sessions should reuse -->
## Preferences
<!-- User/team preferences and conventions -->
## Facts
<!-- Stable repo or environment facts -->
## Pitfalls
<!-- Repeated failure modes and how to avoid them -->
Append a session-open breadcrumb to docs/agent-sessions/memory/YYYY-MM-DD.md:
## HH:MM {session-name} ({scope})
- Started on branch `{branch}`
- Session artifact: `docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/memory.md`
Stage the new files:
git add docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/ docs/agent-sessions/memory/ docs/agent-sessions/MEMORY.md
Print summary — show all three memory paths and remind the user to update the session
memory.md incrementally.
Mode: finalize
Parse $ARGUMENTS — if it equals finalize, run this mode.
Steps
Find the session directory. Look for a directory in docs/agent-sessions/ matching the
current session name and branch scope for today's date. If multiple exist, use the most recent.
If none exist, tell the user to run /session-memory start first.
Check for completeness. Read memory.md. Look for HTML comment placeholders
(<!-- ... -->). List sections that still have only placeholder content and prompt the user to
fill them in before finalizing.
Update PR number. If memory.md still shows (pending) for the PR field and a PR exists
for the current branch, update it:
gh pr view --json number --jq .number
Update session ID. If memory.md still shows (unknown) or (not captured) for the Session
ID field, attempt detection again using the same logic from Detecting Context step 7
(session_meta.payload.id first, then filename UUID, then rollout stem fallback).
Validate metadata completeness. Check that the metadata table in memory.md has been filled
in — Session, Date, Branch, and PR fields should not be placeholders. If any are still
placeholders, warn the user.
Ensure layered files exist, then promote durable memory candidates.
Before promoting, ensure layered memory files exist. This keeps finalize backward-compatible
with older sessions that only have docs/agent-sessions/YYYY-MM-DD-.../memory.md.
- If
docs/agent-sessions/MEMORY.md does not exist, create it using the same template from
start mode.
- If
docs/agent-sessions/memory/YYYY-MM-DD.md does not exist, create it.
Review completed session sections (Key Decisions, Problems Encountered, Outcome,
Follow-ups) and promote only durable items into docs/agent-sessions/MEMORY.md.
Promotion format:
- YYYY-MM-DD: <fact/decision/pitfall> (source: YYYY-MM-DD-{session-name}-{scope})
Also append a session-close breadcrumb to docs/agent-sessions/memory/YYYY-MM-DD.md:
## HH:MM finalize {session-name} ({scope})
- Finalized `YYYY-MM-DD-{session-name}-{scope}`
- Durable memory updated.
Stage and commit the session memory:
git add docs/agent-sessions/
git commit -m "docs(sessions): finalize session memory"
The memory must be committed before the next step can verify it's in the PR's commit chain.
Verify session memory is in the PR's commit chain. Session memories committed to a worktree
branch can get stranded if the PR merges via squash from a different commit history. Check that
the session memory will actually land on main:
a. Check if a PR exists for the current branch:
branch=$(git branch --show-current)
pr_json=$(gh pr view --json number,headRefName,state --jq '.' 2>/dev/null || echo '{}')
pr_number=$(echo "$pr_json" | jq -r '.number // empty')
pr_head=$(echo "$pr_json" | jq -r '.headRefName // empty')
b. If the PR branch differs from the current branch (e.g., you're on a worktree branch but
the PR was created from a different branch), the session memory won't make it to main. Warn:
"Session memory is on branch $branch but PR #N targets branch $pr_head. The memory will
be stranded after merge."
In this case, cherry-pick the session memory commit to the PR branch:
memory_commit=$(git log --oneline -1 --format='%H' -- docs/agent-sessions/)
git switch "$pr_head"
git cherry-pick "$memory_commit"
git push
git switch "$branch"
If cherry-picking is not feasible (e.g., PR branch is on a different remote or has conflicts),
note this in the summary and recommend creating a separate PR for the session memory.
c. If no PR exists yet, remind the agent to ensure the session memory is included when the PR
is created.
Print summary — confirm memory files are complete and committed. List any remaining
placeholder sections as warnings. If the PR branch verification from step 8 flagged any issues,
include them prominently in the summary.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: session-memory-23description: Create or finalize session memory files for the current working session Use when this capability is needed.4---56# Session Memory78Manage session memory artifacts in repos that have opted in via a `docs/agent-sessions/` directory.9Two modes: `start` creates the session directory with a template `memory.md`; `finalize` checks for10completeness and stages everything.1112Use a layered memory model (influenced by OpenClaw):1314- **Session artifact (source of truth for one run):**15 `docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/memory.md`16- **Working memory log (append-only timeline):**17 `docs/agent-sessions/memory/YYYY-MM-DD.md`18- **Durable memory (curated cross-session memory):**19 `docs/agent-sessions/MEMORY.md`2021Session directories still prevent collisions across parallel worktrees, while the log and durable22files make recall easier across many sessions.2324## Memory Rules25261. Never claim memory persistence unless it is written to disk in this repo.272. If the user says "remember", "note this", "save this", or equivalent, write it to the current28 session `memory.md` and clearly mark it if it is durable (decision, preference, stable fact,29 recurring pitfall) so it can be promoted later.303. Use `docs/agent-sessions/memory/YYYY-MM-DD.md` for operational breadcrumbs and chronology during31 the run; do not curate heavily there.324. Update `docs/agent-sessions/MEMORY.md` during `finalize` by promoting durable items from the33 session artifact. Keep entries short, deduplicated, and date-stamped.3435## Prerequisites3637- You must be working inside a repo that has a `docs/agent-sessions/` directory.38- You must be on a feature branch (not `main`/`master`).39- You must not be on detached HEAD (`git branch --show-current` must be non-empty).4041## Detecting Context4243Before either mode, determine:44451. **Session name:** Extract from `$PWD`. If the path contains `.claude/worktrees/<name>/` or46 `.codex/worktrees/<name>/`, use47 `<name>`. Otherwise, use the branch slug (branch name after the last `/`, e.g.,48 `user/add-oauth` → `add-oauth`).492. **Repo root:** Run `git rev-parse --show-toplevel`.503. **Branch:** Run `git branch --show-current`.514. **Scope:** Derive from issue number, PR number, or branch name (in priority order):52 - If the PR body contains `Closes #N` or `Resolves #N`, use `issue-{N}`.53 - If a PR exists for the current branch (`gh pr view --json number,body --jq .`), use `pr-{N}`.54 - If the branch name contains an issue reference (e.g., created by `/pick-up-issue`), extract the55 issue keyword and use `issue-{N}` or the slug as scope.56 - Otherwise, take the branch slug after the `/` (e.g., `bkonkle/add-oauth` → `add-oauth`).575. **Date:** Today's date as `YYYY-MM-DD`.586. **Session directory:** `docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/`.597. **Session ID:** Parse from the agent JSONL transcript path. Prefer the structured60 `session_meta.payload.id` value from the transcript, and include Codex archived transcripts as a61 fallback source.6263 Use this detection order:6465 a. Build candidate transcript list from:66 - `find ~/.codex/sessions -type f -name '*.jsonl' 2>/dev/null`67 - `find ~/.codex/archived_sessions -maxdepth 1 -type f -name '*.jsonl' 2>/dev/null`68 - `find ~/.claude/projects -type f -name '*.jsonl' 2>/dev/null`6970 b. Prefer the most recent candidate whose `session_meta.payload.cwd` contains the current repo71 root path (or current worktree path).7273 c. Extract the session ID:74 - First choice: `jq -r 'select(.type=="session_meta" and .payload.id != null and .payload.id != "") | .payload.id' <file> | head -1`75 - If missing, parse UUID from filename with:76 `grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'`77 - If still missing and filename starts with `rollout-`, use the rollout filename stem (without78 `.jsonl`) as a temporary Session ID and note it is rollout-formatted.7980 d. If no candidate matches, leave as `(unknown)` and note the user can fill it manually.8182If `docs/agent-sessions/` does not exist in the repo root, stop and tell the user the repo has not83opted in. They can opt in by creating `docs/agent-sessions/README.md`.8485## Shell Portability8687- Prefer POSIX-compatible shell snippets in this skill (`sh`/`zsh` safe).88- If you need bash-only builtins (`mapfile`, `read -a`), explicitly run commands through89 `/bin/bash` to avoid zsh failures.9091## Mode: `start`9293Parse `$ARGUMENTS` — if it equals `start` (or is empty), run this mode.9495### Steps96971. **Check for existing session directory.** If `docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/`98 already exists, print its path and note that it's ready for use. Do not overwrite.991002. **Create the session directory:**101102 ```sh103 mkdir -p docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}104 ```1051063. **Create `memory.md`** with this template (fill in known fields, leave placeholders for others):107108 ```markdown109 # Memory: <title — describe the work>110111 | Field | Value |112 | ---------- | ------------------ |113 | Session | {session-name} |114 | Date | YYYY-MM-DD |115 | Session ID | {sessionId} |116 | PR | (pending) |117 | Branch | {branch} |118 | Issue(s) | (none yet) |119120 ## Goal121122 <!-- What this session sets out to accomplish -->123124 ## Key Decisions125126 <!-- 1. **Decision** — Rationale. Alternatives considered. -->127128 ## Approach129130 <!-- Implementation strategy, files changed, patterns followed -->131132 ## Problems Encountered133134 <!-- - **Problem** — Root cause and fix -->135136 ## Outcome137138 <!-- End state: merged, open for review, follow-up needed -->139140 ## Follow-ups141142 <!-- - [ ] Unresolved items for future sessions -->143 ```1441454. **Ensure layered memory files exist:**146147 ```sh148 mkdir -p docs/agent-sessions/memory149 touch "docs/agent-sessions/memory/YYYY-MM-DD.md"150 ```151152 If `docs/agent-sessions/MEMORY.md` does not exist, create it with:153154 ```markdown155 # Durable Memory156157 ## Decisions158159 <!-- Stable decisions that future sessions should reuse -->160161 ## Preferences162163 <!-- User/team preferences and conventions -->164165 ## Facts166167 <!-- Stable repo or environment facts -->168169 ## Pitfalls170171 <!-- Repeated failure modes and how to avoid them -->172 ```1731745. **Append a session-open breadcrumb** to `docs/agent-sessions/memory/YYYY-MM-DD.md`:175176 ```markdown177 ## HH:MM {session-name} ({scope})178 - Started on branch `{branch}`179 - Session artifact: `docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/memory.md`180 ```1811826. **Stage the new files:**183184 ```sh185 git add docs/agent-sessions/YYYY-MM-DD-{session-name}-{scope}/ docs/agent-sessions/memory/ docs/agent-sessions/MEMORY.md186 ```1871887. **Print summary** — show all three memory paths and remind the user to update the session189 `memory.md` incrementally.190191## Mode: `finalize`192193Parse `$ARGUMENTS` — if it equals `finalize`, run this mode.194195### Steps1961971. **Find the session directory.** Look for a directory in `docs/agent-sessions/` matching the198 current session name and branch scope for today's date. If multiple exist, use the most recent.199 If none exist, tell the user to run `/session-memory start` first.2002012. **Check for completeness.** Read `memory.md`. Look for HTML comment placeholders202 (`<!-- ... -->`). List sections that still have only placeholder content and prompt the user to203 fill them in before finalizing.2042053. **Update PR number.** If `memory.md` still shows `(pending)` for the PR field and a PR exists206 for the current branch, update it:207208 ```sh209 gh pr view --json number --jq .number210 ```2112124. **Update session ID.** If `memory.md` still shows `(unknown)` or `(not captured)` for the Session213 ID field, attempt detection again using the same logic from Detecting Context step 7214 (`session_meta.payload.id` first, then filename UUID, then rollout stem fallback).2152165. **Validate metadata completeness.** Check that the metadata table in `memory.md` has been filled217 in — Session, Date, Branch, and PR fields should not be placeholders. If any are still218 placeholders, warn the user.2192206. **Ensure layered files exist, then promote durable memory candidates.**221222 Before promoting, ensure layered memory files exist. This keeps `finalize` backward-compatible223 with older sessions that only have `docs/agent-sessions/YYYY-MM-DD-.../memory.md`.224225 - If `docs/agent-sessions/MEMORY.md` does not exist, create it using the same template from226 `start` mode.227 - If `docs/agent-sessions/memory/YYYY-MM-DD.md` does not exist, create it.228229 Review completed session sections (`Key Decisions`, `Problems Encountered`, `Outcome`,230 `Follow-ups`) and promote only durable items into `docs/agent-sessions/MEMORY.md`.231232 Promotion format:233234 ```markdown235 - YYYY-MM-DD: <fact/decision/pitfall> (source: YYYY-MM-DD-{session-name}-{scope})236 ```237238 Also append a session-close breadcrumb to `docs/agent-sessions/memory/YYYY-MM-DD.md`:239240 ```markdown241 ## HH:MM finalize {session-name} ({scope})242 - Finalized `YYYY-MM-DD-{session-name}-{scope}`243 - Durable memory updated.244 ```2452467. **Stage and commit the session memory:**247248 ```sh249 git add docs/agent-sessions/250 git commit -m "docs(sessions): finalize session memory"251 ```252253 The memory must be committed before the next step can verify it's in the PR's commit chain.2542558. **Verify session memory is in the PR's commit chain.** Session memories committed to a worktree256 branch can get stranded if the PR merges via squash from a different commit history. Check that257 the session memory will actually land on main:258259 a. **Check if a PR exists for the current branch:**260 ```sh261 branch=$(git branch --show-current)262 pr_json=$(gh pr view --json number,headRefName,state --jq '.' 2>/dev/null || echo '{}')263 pr_number=$(echo "$pr_json" | jq -r '.number // empty')264 pr_head=$(echo "$pr_json" | jq -r '.headRefName // empty')265 ```266267 b. **If the PR branch differs from the current branch** (e.g., you're on a worktree branch but268 the PR was created from a different branch), the session memory won't make it to main. Warn:269 "Session memory is on branch `$branch` but PR #N targets branch `$pr_head`. The memory will270 be stranded after merge."271272 In this case, **cherry-pick the session memory commit to the PR branch**:273274 ```sh275 memory_commit=$(git log --oneline -1 --format='%H' -- docs/agent-sessions/)276 git switch "$pr_head"277 git cherry-pick "$memory_commit"278 git push279 git switch "$branch"280 ```281282 If cherry-picking is not feasible (e.g., PR branch is on a different remote or has conflicts),283 note this in the summary and recommend creating a separate PR for the session memory.284285 c. **If no PR exists yet**, remind the agent to ensure the session memory is included when the PR286 is created.2872889. **Print summary** — confirm memory files are complete and committed. List any remaining289 placeholder sections as warnings. If the PR branch verification from step 8 flagged any issues,290 include them prominently in the summary.291292---293> Converted and distributed by [TomeVault](https://tomevault.io/claim/bkonkle-dev) — claim your Tome and manage your conversions.294<!-- tomevault:4.0:skill_md:2026-04-13 -->