AgentStack
SKILL verified Apache-2.0 Self-run

Wrapup

skill-onebrain-ai-onebrain-wrapup · by onebrain-ai

Wrap up and save the current session summary to the session log. Use at end of session when the user says 'bye', 'wrap up', 'save session', or an end-of-session signal is detected. /wrapup writes to 07-logs/ only. Do NOT use for: promoting insights to memory/ (use recap), synthesizing a topic across sessions (use distill), or teaching a single preference (use learn).

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add skill-onebrain-ai-onebrain-wrapup

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Wrapup? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Session Summary (TL;DR)

Generates a summary of this session and saves it to the logs folder for future recall.


Scope

/wrapup writes the session log only. It does NOT promote insights to memory/ — that is /recap's responsibility. Do not write to MEMORY.md or memory/ files.


Session Log Frontmatter

See skills/startup/references/session-formats.md → Session Log Format for frontmatter variants and body sections. Never add recapped: or topics: — those are populated by /recap later.


Step 0: Active Pause Thread Detection

Run this BEFORE Step 1.

  1. Read [logs_folder]/pause/_active.md. If absent or empty → set wrapup_mode = "session"; skip to Step 1 (zero-overhead path for non-pause sessions).
  2. If a slug is present: parse the file's single-line content as slug. Glob [logs_folder]/pause/*-{slug}-pause-*.mdpause_count (file count) and derive first_date = earliest YYYY-MM-DD date prefix among matched files (used in Step 3's question text).
  3. Use AskUserQuestion:

Question: "Active pause thread: {slug} ({pausecount} snapshots since {firstdate}). Wrap up this thread now?" Options:

  • "Yes — consolidate into one session log" (sets wrapup_mode = "thread")
  • "No — wrapup today's work only; keep pause thread active" (sets wrapup_mode = "session")
  1. If wrapup_mode = "session" AND active pause exists → fall through to Step 0b: Auto-Finalize Pause (below) BEFORE proceeding to Step 1.
  2. If wrapup_mode = "thread" → proceed to Step 1 normally, then branch in Step 4 (see Step 4 modifications below).

Step 0b: Auto-Finalize Pause (Session-mode wrapup with active thread)

Runs only when wrapup_mode = "session" AND _active.md exists.

Apply the three skip conditions from skills/pause/SKILL.md → Auto-Finalize section:

  1. No-activity: if no checkpoint file exists for current session_token, skip Auto-Finalize.
  2. Already-captured-this-session: if latest pause file's frontmatter session_token matches current AND no checkpoint mtime > pause file mtime, skip.
  3. No-pause-files-and-untouched: if no pause file exists for slug AND newest checkpoint mtime Note on cleanup: Checkpoints are deleted (not annotated) after the session log is successfully written. Any checkpoint file that still exists is unmerged by definition; no merged: filter is needed.

Step 1b: Orphan Recovery Scan

After Step 1, scan for unmerged checkpoints belonging to other sessions (orphans).

Variable scope (used throughout this step): Initialize two lists at the top of Step 1b and keep them alive until Step 7 reads them at the end of /wrapup:

  • skipped_active = []{path, age_minutes, reason} records, where reason{"active", "age_unknown", "concurrent_during_recovery", "delete_failed", "already_recovered", "marker_write_failed"}. Both the Active-Session Guard and Auto-Recover Each Orphan Group append to this list. When adding a new value to this enum, also add a corresponding row to the {reason_summary} rendering table in Step 7 (search this file for {reason_summary} rendering); unmapped values render via the catch-all fallback row but the user-facing string is generic, so an explicit row is required for new values.
  • orphaned_recovered_logs = [] — paths of recovered session logs left on disk by an aborted recovery. Two abort sources feed this list: (1) concurrency abort in step (g) when the owning session writes a new checkpoint mid-recovery and the recovered-log delete itself also fails; (2) marker re-read failure in step (f) when the recovery marker is missing from the just-written log (LLM omission, partial write, encoding glitch). Both produce a recovered log without a deleted checkpoint group; the user must manually reconcile. Listed in its own Step 7 block (these are not checkpoint files, so they don't fit the checkpoint-file heading).

Scan Scope

Glob [logs_folder]/checkpoint/*-checkpoint-*.md (flat — post-v2.4.0 all checkpoints live in one directory regardless of date). No date filter: checkpoint/ is ephemeral (cleaned by /wrapup after each session), so any file surfacing here is either an active cross-harness session (caught by the Active-Session Guard below) or a real orphan that needs recovery.

Identify Orphans

From all found checkpoint files:

  1. Parse session_token from each filename: the alphanumeric segment between the date and the literal word "checkpoint" in pattern YYYY-MM-DD-{session_token}-checkpoint-NN.md. If empty, apply Legacy token handling (see below) rather than skipping.
  2. Exclude files where the parsed session_token exactly equals the current session token (those belong to the current session, already handled in Step 1). Do not use substring/contains matching — only exact equality.
  3. Group remaining files by their parsed session_token. Store the file list of each group as group_files (the baseline used by step (g)'s concurrency re-glob below); never re-derive the group fresh later in this step.

Legacy token handling: If the parsed segment is a 6-character random string (pre-v1.10.4 format), still include the file in orphan recovery. Group these files under a synthetic key legacy-{segment} and process them the same way as regular groups. This ensures migration from v1.10.3 and earlier does not lose checkpoints. Note each legacy file in the Step 7 report as a warning.

If no orphan groups found: skip to Step 2.

Active-Session Guard (Time Window)

> Why this guard exists: A non-current token does NOT mean the session is dead. When two harnesses (e.g. Claude + Gemini) run in the same vault, each sees the other's in-flight checkpoints as "non-current token". Without this guard, the first /wrapup to run would auto-recover the other harness's active checkpoints into a fake session log and delete the originals — silently corrupting the live session. Token != mine ≠ session is dead.

For each orphan group from the Identify Orphans step above, decide between recover and skip-active by file age (the skipped_active list was initialized at the top of Step 1b):

  1. Resolve the threshold once (before scanning groups): read onebrain.yml's checkpoint.minutes (defaults to 30 when the key is absent) and compute threshold_minutes = max(60, 2 * checkpoint.minutes). Examples: default 30 → 60, raised 60 → 120, raised 90 → 180. If onebrain.yml is missing, malformed, or checkpoint.minutes is non-positive/non-numeric, fall back to threshold_minutes = 60 — the recovery flow is critical-path; never block on a config issue.
  2. Compute now_epoch once: now_epoch=$(date +%s).
  3. For every checkpoint file in the group, get its mtime as epoch seconds:
  • macOS / BSD: stat -f '%m'
  • Linux / GNU: stat -c '%Y'
  • Take the maximum across all files in the group as group_newest_mtime.
  1. Compute age_minutes = (now_epoch - group_newest_mtime) / 60 (integer division is fine).
  2. Fail-safe — destructive default is forbidden. If any of the following is true, mark the group as skip-active (do NOT recover):
  • any stat call failed (file vanished mid-walk, EACCES, NFS error, etc.)
  • group_newest_mtime is empty / unparseable
  • age_minutes is negative (clock skew, future mtime)

When ambiguity is detected, append every file path in the group to skipped_active as {path, age_minutes: -1, reason: "age_unknown"} and continue with the next group. Never fall through to recover when age cannot be determined.

  1. If age_minutes = threshold_minutes — the group looks dead: fall through to Auto-Recover Each Orphan Group below for this group only.

The threshold gives the owning session a buffer of two full checkpoint windows (the auto-checkpoint hook fires every checkpoint.messages messages or checkpoint.minutes minutes). A group whose newest checkpoint is older than that has missed at least two windows — a strong "session dead" signal. The max(60, 2 * checkpoint.minutes) policy preserves the PR #156 baseline (60 min) for default-config users while scaling proportionally for users who raised checkpoint.minutes. False-positives (idle but live sessions older than the threshold) are non-destructive: nothing was read, written, or deleted; the owning user's next /wrapup writes its own session log normally and consumes the still-on-disk checkpoints.

> Symmetry with onebrain checkpoint orphans: the CLI applies the identical max(60, 2 * checkpoint.minutes) rule (in onebrain-ai/onebrain-clicrates/onebrain-fs/src/orphan/, is_group_active_or_ambiguous) so the startup banner and the recovery skill agree on what is and isn't an orphan. If you change this policy in one place, change it in the other.

Auto-Recover Each Orphan Group

Progress signal: if there are more than 3 orphan groups to recover, emit a one-line progress signal between groups so the user knows the skill is making progress: Recovering orphan group {n}/{N} ({date})…. Skip the signal when N ≤ 3 (recovery is fast enough that the signal would be noise).

For each orphan group (process in chronological order by date in filename):

a. Already-recovered short-circuit. Before reading checkpoint files, glob [logs_folder]/session/YYYY/MM/YYYY-MM-DD-session-*.md for the group's date (using the orphan date's YYYY/MM). For each match, search the file for the standardised recovery marker. The marker is ` where {token} is the orphan group's session token and {date}` is the group's date.

> Anchored match required (security): match the marker only when it appears at the start of a line — i.e., either the literal string \n or the file beginning with `. A bare substring match would false-positive on session logs whose body quotes the marker as documentation (e.g., a meta-note about how the recovery flow works). The destructive consequence of a false-positive is checkpoint deletion based on a documentation quote — not acceptable. Use rg -n -F with --multiline and a (?m)^ anchor, or grep the file line-by-line. **Strip trailing \r from each line before the startswith check** — Windows-edited logs use CRLF endings; without this the line literal \r won't match the bare prefix and a legitimate already-recovered marker is silently missed. After CRLF strip, check line.startswith(' body marker as the first body line. The marker must appear once per group recovered into this log; if a single recovery pass aggregates multiple groups (rare — date-grouping usually yields one group per date), emit one marker line per group on consecutive lines before the # Session Summary` heading. Apply the Preservation rule from Step 4 below: deduplication only, no summarization. Every unique decision, action item, open question, learning, and topic from every checkpoint must appear in the recovered session log.

f. Verify the session log exists and is non-empty before continuing. Marker re-read check (required): re-read the file from disk and confirm the ` marker line is present at the start of a line, before the # Session Summary : heading. If the marker is missing (LLM omission, partial write, encoding glitch), the next /wrapup's already-recovered short-circuit will fail to detect this log and could re-recover the same checkpoints into a duplicate session log. To prevent that destructive path, treat a missing-marker as **abort recovery for this group**: do NOT proceed to step (g) (no delete), append the session log path to orphanedrecoveredlogs, and for each file in groupfiles append {path, ageminutes, reason: "markerwritefailed"} to skipped_active`. The user sees both blocks in Step 7 and can investigate the recovered log + the still-present checkpoints together.

g. Delete checkpoint files for this group after confirming step f succeeded.

  • Pre-delete re-stat (concurrency guard) — runs ONCE before any deletes: re-stat every file in group_files (stored in Identify Orphans step 3) AND re-glob the group's filename pattern (YYYY-MM-DD-{token}-checkpoint-*.md) under [logs_folder]/checkpoint/ (flat). The owning session became active during recovery if either of these holds:
  • any file's mtime has changed since the Active-Session Guard's stat above, OR
  • the re-glob result contains a path NOT present in group_files (set difference: re_glob_files \ group_files is non-empty).
  • If concurrent activity is detected: abort the delete entirely for this group. Then attempt to delete the recovered session log written in step (e) so it does not leak duplicate content into the vault. For each file in group_files, append {path, age_minutes, reason: "concurrent_during_recovery"} to skipped_active (use the original age_minutes from the Active-Session Guard). If the recovered-log delete itself fails, append the recovered-log path to orphaned_recovered_logs (a separate list initialized at the top of Step 1b) so the user sees it under its own Step 7 block — these are session-log files, not checkpoint files, and conflate poorly with the checkpoint-file heading. Continue with the next group.
  • If no concurrent activity: delete each file in group_files. Per-file failure rule: if an individual rm fails (EACCES, NFS hiccup, etc.), do NOT abort the whole group — append {path, age_minutes, reason: "delete_failed"} to skipped_active (reuse the original age_minutes from the Active-Session Guard, never 0) and continue with the next file. The recovered session log is already written; the next /wrapup's already-recovered short-circuit (step a) will detect that the orphaned checkpoint's content is already persisted and clean it up.
  • Stage discipline (do not conflate the two rules above): the concurrency check runs ONCE at the top of step (g). After it passes, individual rm failures are NEVER interpreted as concurrency — they record delete_failed per-file and the loop continues. Do not re-run the concurrency check between per-file deletes; do not promote a per-file delete_failed to concurrent_during_recovery. The only group-level abort path is the pre-delete concurrency check.
  • Guard: only delete AFTER step f is confirmed AND the re-stat shows no concurrent activity. Never delete before.

h. Track recovered sessions: append {date} → session-NN.md ({C} checkpoints) to a recovered_sessions list for the final report, where {C} is the number of checkpoint files recovered for this group.


Step 2: Determine Session File Name

  1. Using the date from Step 1, extract YYYY, MM (zero-padded month), and DD (zero-padded day).
  2. List files in [logs_folder]/session/YYYY/MM/ matching YYYY-MM-DD-session-*.md — use today's actual date as a literal prefix (e.g. 2026-04-25-session-*.md), not as a wildcard. Only count sessions from today.
  3. The next session number = count of matches + 1 (zero-padded to 2 digits: 01, 02, etc.)
  4. Verify YYYY-MM-DD-session-NN.md does not already exist before writing; if it does, increment NN until a free slot is found.
  5. File name: [logs_folder]/session/YYYY/MM/YYYY-MM-DD-session-NN.md

Step 3: Review the Session

Reflect on the conversation that just occurred. Identify:

  • Main topic(s) : What did we work on?
  • Key decisions made : Any choices, directions, or conclusions reached
  • Insights or learnings : New understanding, patterns noticed, things discovered
  • What worked / didn't work : Approaches or tools that helped, and anything that slowed us down or failed (omit if nothing notable)
  • Action items : Tasks to do, things to follow up on
  • Open questions : Unresolved questions or things to investigate

Step 4: Write the Session Log

Branch on wrapup_mode (set in Step 0):

  • If wrapup_mode = "session" → follow the existing flow below (no changes).
  • If wrapup_mode = "thread" → use the **Thread Wrapup Bra

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.