/handoff
End a Codex work session. Stores durable captures, writes a narrative session log, and automatically applies typed item-level deltas to the current Space Brief. Invoked as /handoff.
$ npx -y skills add 7xuanlu/wenlan --skill handoff --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/handoff
Context preview
The summary Claude sees to decide when to auto-load this skill.
End a Codex work session. Stores durable captures, writes a narrative session log, and automatically applies typed item-level deltas to the current Space Brief. Invoked as /handoff.
SKILL.md
handoff.SKILL.mdname: handoff
description: >
End a Codex work session. Stores durable captures, writes a narrative session
log, and automatically applies typed item-level deltas to the current Space
Brief. Invoked as /handoff.
allowed-tools: ["Bash", "mcp__wenlan__capture", "mcp__wenlan__list_pending"]
user-invocable: true
/handoff
Close the session with three separate artifacts:
1. A typed update to the daemon-owned Space Brief. 2. Durable MCP captures in that Space. 3. A chronological session log in `~/.wenlan/sessions/`.
The daemon Brief is current-work authority. Its `~/.wenlan/sessions/_status/<space>.md` projection is a one-way human receipt. Never read, edit, or overwrite that receipt as authority.
1. Resolve repository and Space
repo="$(git -C "$PWD" rev-parse --show-toplevel 2>/dev/null || true)"
if [ -n "$repo" ]; then
common="$(git -C "$PWD" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)"
case "$common" in
*/.git) project="$(basename "$(dirname "$common")")" ;;
*) project="$(basename "$repo")" ;;
esac
else
project=""
fi
resolved="$(plugin-codex/bin/resolve-space.sh --cwd "$PWD" 2>/dev/null)"
space="$(printf '%s\n' "$resolved" | cut -f1)"
source_layer="$(printf '%s\n' "$resolved" | cut -f2)"
if [ -z "$space" ] && [ -n "$project" ]; then
space="$project"
source_layer="cwd-repo-new"
fiPrint `space` and `source_layer`. Explicit pins, defaults, and mappings still win. `cwd-repo-new` is the approved first-handoff fallback: use the canonical repository basename, which the user can override through normal Space config. Do not invent any other Space name.
Outside a Git repository, do not derive a new Space from the directory basename. If resolution still leaves `space` empty, skip the Brief read and typed update, do not issue Space-scoped captures, and continue with the unscoped session log and any unscoped durable captures.
2. Read the Brief before composing deltas
W="$(command -v wenlan || echo "$HOME/.wenlan/bin/wenlan")"
brief_before=""
brief_absent=0
if [ -n "$space" ]; then
if [ "$source_layer" = "cwd-repo-new" ]; then
space_probe_status=0
space_probe="$("$W" --format json spaces show "$space" 2>&1)" || space_probe_status=$?
if [ "$space_probe_status" -eq 0 ]; then
brief_before="$("$W" --format json --space "$space" brief)"
source_layer="cwd-repo"
elif [ "$space_probe" = "Error: space '$space' not found" ]; then
brief_absent=1
else
printf "%s\n" "$space_probe" >&2
exit "$space_probe_status"
fi
else
brief_before="$("$W" --format json --space "$space" brief)"
fi
fiRead the Brief before composing deltas. This read is mandatory before any Brief delta is authored for a registered Space. Retain the Brief version and every item's exact ID, version, state, text, added date, and gate. Use `last_handoff_at` for the pending-capture window.
`brief_not_created` is valid and write-free. Use summary `expected_version: 0`. For `cwd-repo-new`, prove the Space is absent with `spaces show` before composing deltas. Accept only the exact CLI error `Error: space '<name>' not found` as first-handoff absence; any other probe failure stops the handoff. An absent Space cannot have a Brief or existing items, so use `expected_version: 0` and author no existing-item mutations. The typed update may then create the Space and Brief.
3. Preview pending captures and gather evidence
Call `mcp__wenlan__list_pending(limit=50)`. Filter by `created_at >= last_handoff_at`, or 12 hours ago when absent. Show at most three when any match, then continue automatically; `/curate captures` remains opt-in.
For a repository, inspect a bounded recent log, short status, diff stat, and worktree list. Combine that evidence with the conversation. Draft atomic captures only for durable decisions, lessons, gotchas, corrections, preferences, and facts. Skip transient or git-recoverable state.
4. Build and apply one typed Brief update
Compare the session outcome with `brief_before` and write one `BriefUpdateRequest` JSON file:
{
"space": "<resolved Space>",
"caller_id": "codex",
"operation_id": "<unique id retained for retries of this handoff>",
"summary": {
"text": "<concise last-session summary>",
"expected_version": 0
},
"mutations": []
}Use the existing Brief version instead of `0` when present. If `space` is empty, skip this typed update entirely.
- `add`: genuinely new open work, in `active` or `backlog`, with an optional
gate.
- `edit`, `move`, `set_gate`, and `complete`: use the exact existing item ID.
- Every delta for one existing item uses the same version from the pre-handoff Brief snapshot.
Do not chain versions generated by earlier deltas in the same request.
- `complete` removes the item; there is no Done state.
- Never fuzzy-match. Leave an ambiguous item unchanged.
- Never auto-demote untouched Active work.
- Do not add an unchanged duplicate.
Apply exactly once:
"$W" --format json --space "$space" brief update --file "$update_file"
Do not ask approval for this normal handoff update. Interpret `applied`, `conflicts`, `projection_path`, and `warnings` independently. Non-overlapping changes may commit while a stale same-item delta conflicts. Re-read before any safe mechanical reconciliation; never guess.
Apply the Brief update before Space-scoped captures when this fallback is new. That creates the basename Space through the typed handoff path without making a read or a capture create state. If this first update fails, stop Space-scoped captures and report the exact failure.
5. Store durable captures
For each drafted durable item, call:
mcp__wenlan__capture(
content="<self-contained statement with why>",
memory_type="<decision|lesson|gotcha|preference|fact>",
space="<resolved Space>"
)
Use one atomic item per call. Do not ask about ordinary captures. Pause only for a contradiction,
Read more
name: handoff description: > End a Codex work session. Stores durable captures, writes a narrative session log, and automatically applies typed item-level deltas to the current Space Brief. Invoked as /handoff. allowed-tools: ["Bash", "mcp__wenlan__capture", "mcp__wenlan__list_pending"] user-invocable: true
/handoff
Close the session with three separate artifacts:
1. A typed update to the daemon-owned Space Brief. 2. Durable MCP captures in that Space. 3. A chronological session log in `~/.wenlan/sessions/`.
The daemon Brief is current-work authority. Its `~/.wenlan/sessions/_status/<space>.md` projection is a one-way human receipt. Never read, edit, or overwrite that receipt as authority.
1. Resolve repository and Space
repo="$(git -C "$PWD" rev-parse --show-toplevel 2>/dev/null || true)"
if [ -n "$repo" ]; then
common="$(git -C "$PWD" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)"
case "$common" in
*/.git) project="$(basename "$(dirname "$common")")" ;;
*) project="$(basename "$repo")" ;;
esac
else
project=""
fi
resolved="$(plugin-codex/bin/resolve-space.sh --cwd "$PWD" 2>/dev/null)"
space="$(printf '%s\n' "$resolved" | cut -f1)"
source_layer="$(printf '%s\n' "$resolved" | cut -f2)"
if [ -z "$space" ] && [ -n "$project" ]; then
space="$project"
source_layer="cwd-repo-new"
fiPrint `space` and `source_layer`. Explicit pins, defaults, and mappings still win. `cwd-repo-new` is the approved first-handoff fallback: use the canonical repository basename, which the user can override through normal Space config. Do not invent any other Space name.
Outside a Git repository, do not derive a new Space from the directory basename. If resolution still leaves `space` empty, skip the Brief read and typed update, do not issue Space-scoped captures, and continue with the unscoped session log and any unscoped durable captures.
2. Read the Brief before composing deltas
W="$(command -v wenlan || echo "$HOME/.wenlan/bin/wenlan")"
brief_before=""
brief_absent=0
if [ -n "$space" ]; then
if [ "$source_layer" = "cwd-repo-new" ]; then
space_probe_status=0
space_probe="$("$W" --format json spaces show "$space" 2>&1)" || space_probe_status=$?
if [ "$space_probe_status" -eq 0 ]; then
brief_before="$("$W" --format json --space "$space" brief)"
source_layer="cwd-repo"
elif [ "$space_probe" = "Error: space '$space' not found" ]; then
brief_absent=1
else
printf "%s\n" "$space_probe" >&2
exit "$space_probe_status"
fi
else
brief_before="$("$W" --format json --space "$space" brief)"
fi
fiRead the Brief before composing deltas. This read is mandatory before any Brief delta is authored for a registered Space. Retain the Brief version and every item's exact ID, version, state, text, added date, and gate. Use `last_handoff_at` for the pending-capture window.
`brief_not_created` is valid and write-free. Use summary `expected_version: 0`. For `cwd-repo-new`, prove the Space is absent with `spaces show` before composing deltas. Accept only the exact CLI error `Error: space '<name>' not found` as first-handoff absence; any other probe failure stops the handoff. An absent Space cannot have a Brief or existing items, so use `expected_version: 0` and author no existing-item mutations. The typed update may then create the Space and Brief.
3. Preview pending captures and gather evidence
Call `mcp__wenlan__list_pending(limit=50)`. Filter by `created_at >= last_handoff_at`, or 12 hours ago when absent. Show at most three when any match, then continue automatically; `/curate captures` remains opt-in.
For a repository, inspect a bounded recent log, short status, diff stat, and worktree list. Combine that evidence with the conversation. Draft atomic captures only for durable decisions, lessons, gotchas, corrections, preferences, and facts. Skip transient or git-recoverable state.
4. Build and apply one typed Brief update
Compare the session outcome with `brief_before` and write one `BriefUpdateRequest` JSON file:
{
"space": "<resolved Space>",
"caller_id": "codex",
"operation_id": "<unique id retained for retries of this handoff>",
"summary": {
"text": "<concise last-session summary>",
"expected_version": 0
},
"mutations": []
}Use the existing Brief version instead of `0` when present. If `space` is empty, skip this typed update entirely.
- `add`: genuinely new open work, in `active` or `backlog`, with an optional
gate.
- `edit`, `move`, `set_gate`, and `complete`: use the exact existing item ID.
- Every delta for one existing item uses the same version from the pre-handoff Brief snapshot.
Do not chain versions generated by earlier deltas in the same request.
- `complete` removes the item; there is no Done state.
- Never fuzzy-match. Leave an ambiguous item unchanged.
- Never auto-demote untouched Active work.
- Do not add an unchanged duplicate.
Apply exactly once:
"$W" --format json --space "$space" brief update --file "$update_file"
Do not ask approval for this normal handoff update. Interpret `applied`, `conflicts`, `projection_path`, and `warnings` independently. Non-overlapping changes may commit while a stale same-item delta conflicts. Re-read before any safe mechanical reconciliation; never guess.
Apply the Brief update before Space-scoped captures when this fallback is new. That creates the basename Space through the typed handoff path without making a read or a capture create state. If this first update fails, stop Space-scoped captures and report the exact failure.
5. Store durable captures
For each drafted durable item, call:
mcp__wenlan__capture( content="<self-contained statement with why>", memory_type="<decision|lesson|gotcha|preference|fact>", space="<resolved Space>" )
Use one atomic item per call. Do not ask about ordinary captures. Pause only for a contradiction,
Showing the first part of this file.
Wenlan is a knowledge base for the AI-native age. Your AI agents capture what they learn, Wenlan keeps it current and distills it into source-cited wiki pages you can trust
Other skills on wenlan.
- /prove
Per-surface verification loops for wenlan — daemon, cli, mcp, plugin, suite strength (mutation), behavior trace, weekly sweep. Routes to scripts; every check records evidence via attest. Deeper than the built-in verify skill — use prove for mutation audits, behavior tracing, and
Open skill - /run-wenlan
Build, launch, and stop the wenlan daemon (wenlan-server) for local dev and verification. Use when asked to run or restart the daemon, or before driving any surface (HTTP, CLI, MCP) against a live instance.
Open skill - /verify
Drive/evidence recipe for verifying wenlan changes at their real surfaces (daemon HTTP, CLI, MCP stdio). The handle file the built-in verify protocol expects; launch primitives live in the run-wenlan skill, deeper machinery (mutation audit, behavior trace, weekly sweep) in the
Open skill - /brief
Read the current Space-owned project Brief from Wenlan for Codex. With an optional topic, appends separately labeled related context from the same Space. Invoked as /brief [topic] when resuming work or asking to catch up.
Open skill - /capture
Save a durable memory to Wenlan from Codex. Use proactively when the user states a preference, makes a decision, corrects you, or shares a durable fact. Invoked as /capture <content>.
Open skill - /curate
Review pending Wenlan captures, revisions, or daemon refinements from Codex. Use for explicit audit walks after /brief or /handoff surfaces pending work. Invoked as /curate captures, /curate revisions, or /curate refinements.
Open skill

