Use when the user says "prepare a handover", "handover", "write a handoff", "save session state", "hand this off", before a context compaction/reset, at session end, or before ending work on a long task — writes a comprehensive, organized, minimal-but-lossless session handover so a fresh session can resume without re-deriving or guessing anything.
Installs into .claude/skills of the current project.
Are you the author of Anti Hall Handover?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/talas9-anti-hall-handover)
---
name: anti-hall-handover
description: Use when the user says "prepare a handover", "handover", "write a handoff", "save session state", "hand this off", before a context compaction/reset, at session end, or before ending work on a long task — writes a comprehensive, organized, minimal-but-lossless session handover so a fresh session can resume without re-deriving or guessing anything.
---
# anti-hall handover for Codex
Codex-native mirror of the Claude `handover` skill — same artifact contract
and templates; only platform phrasing differs (no `/compact` references,
`AGENTS.md` instead of `CLAUDE.md`).
**Triggered automatically, too.** `hooks/auto-handover.js` (UserPromptSubmit, shared
verbatim with the Claude plugin) watches the main agent's estimated context usage and, at
85% by default (`autoHandover` section of `~/.anti-hall/settings.json`, or
`ANTIHALL_AUTO_HANDOVER_PCT`; `anti-hall-settings` skill to change it), injects
a directive to run THIS skill's contract yourself, right now, without asking the user
first — same self-write mandate as below. A long autonomous turn that never passes a
user prompt gets the same directive once at a `Stop` (`hooks/auto-handover-pause-nag.js`,
shared latch, never while `stop_hook_active`). If you're reading this skill because that
directive fired, follow it exactly as written; nothing else changes.
Prepares a session handover: perishable job state (goal, current position,
next executable step, decisions, dead ends, verification status) written to
disk so a fresh session — with no memory of this one — resumes correctly.
Built from anti-hall's `https://github.com/talas9/anti-hall/blob/main/docs/KB-session-handover.md` (repo-clone-only, not
bundled with a packaged install — cite it as the anti-hall repo's own doc,
since the target project won't have that path).
**Handover ≠ memory.** Durable rules, conventions, and architecture facts belong
in `AGENTS.md`/project memory — they persist because they're always true. A
handover is job state for THIS session — it's true today and stale next week.
Never write durable knowledge into a handover file (it'll rot there, unread);
never write perishable job state into `AGENTS.md` (it'll bloat the always-loaded
context). If you learn something durable while writing a handover, route it to
`AGENTS.md`/project memory separately — don't smuggle it into `decisions.md`.
## Self-write mandate (read first)
The handover is written **by the agent holding the session context** —
**never delegate the writing to a subagent**: it never lived this session, so
its reconstruction loses decision/trial fidelity (a field failure: a session
delegated handover-writing to a subagent even after loading this skill).
Documented exception to delegation-first/orchestrate-only doctrine. Parity
note: `edit-guard.js`'s wrong-location redirect and `model-routing-guard.js`'s
spawn-intent advisory (shared files) carry this rule's logic, but Codex's
`hooks.json` wires neither onto a Write/Edit or Agent-spawn matcher (it does
register `tasklist-guard.js` and `handover-resume.js`) — treat this as YOUR
discipline here, not yet a mechanical rail. Use the Write/Edit tool for
every file below, never a Bash heredoc (`cat > f <<EOF`) — a heredoc body is
scanned as shell by `git-guard.js` (shared with Claude Code), and prose that
merely mentions a git command near backticks can trip a block Write/Edit
never hit in the first place.
## Artifact layout
**Handovers are never committed; the only format is the layout below** — no flat
files, no `CONTINUE-HERE.md`, no copy under `docs/`. git-guard blocks a commit that
includes one and doctor warns about strays.
```
.anti-hall/handovers/
INDEX.md # global index — one row per handover, appended, never rewritten
<YYYY-MM-DD>/<session-id>/
HANDOVER.md # seq 1, the main file (<=200 lines, front-loaded)
HANDOVER-2.md, HANDOVER-3.md, ... # later handovers in the SAME session; each names its predecessor
state.md # repo/git/env state
decisions.md # every decision, in sequence, with rejected alternatives
trials.md # everything attempted, chronological, incl. abandoned approaches
knowledge.md # KB/docs/research consulted, learned facts, gotchas, source-of-truth pointers
```
This mirrors `.anti-hall/progress/` and `.anti-hall/history/` — same navigation
model: read `INDEX.md` first, open only what it says is relevant.
## Session id and date
- Prefer a stable session/thread identifier from the runtime if available.
- Otherwise fall back to the same platform-neutral style: a sha1 hash of the
transcript/log path, first 16 hex characters, if such a path is knowable. If
neither is available, use a short, stable human slug (lowercase, hyphenated,
e.g. `auth-refactor-session`) — reuse the SAME slug across handovers written
in the same session, don't regenerate it each call.
- Date = today, `YYYY-MM-DD`.
## Sequencing
Count existing `HANDOVER*.md` files in `<date>/<session-id>/`. Seq = count + 1.
- Seq 1 → `HANDOVER.md`.
- Seq N>1 → `HANDOVER-N.md`, and its "Predecessor" slot names the immediately
prior file (`HANDOVER.md` for seq 2, `HANDOVER-2.md` for seq 3, etc).
If re-invoked for a seq that already exists in this same session (rare — e.g. the
agent explicitly asks to refresh the just-written handover), UPDATE that file in
place rather than incrementing again.
**Carry-forward rule (seq N>1).** A later handover is often written from an
already-compacted context, and every re-summary loses more (anti-hall repo
`https://github.com/talas9/anti-hall/blob/main/docs/KB-handover-research.md`, P3/P4: never compact a compaction). So:
- COPY the predecessor's Session rules, Done + Verified rows and NOT-verified
rows **verbatim, with their original evidence**, each tagged
`(carried from <predecessor file>)` — never re-summarize or re-word them.
- Drop a carried row only when this session has fresh evidence it no longer
applies, and say so in one line (`superseded: <row> — <evidence>`).
- New rows come only from evidence gathered since the predecessor was written.
## HANDOVER.md contract
**≤200 lines. Front-loaded**: the first ~15 lines are Situation (2-3 lines) plus a
single concrete NEXT ACTION — one thing the next session can execute immediately,
no interpretation required. Context re-injection mechanisms in general truncate
by keeping a file's START (https://github.com/talas9/anti-hall/blob/main/docs/KB-session-handover.md, principle O4) —
everything load-bearing goes early; sources and full chronology go last, where
losing them costs least.
Fixed section order, every time (SBAR-derived, https://github.com/talas9/anti-hall/blob/main/docs/KB-session-handover.md's
consolidated schema):
1. **Situation** — 2-3 lines: what this session was doing.
1a. **Trigger** — one line, right under Situation: why this handover is being
written, one of `auto-threshold` / `user-request` / `restart-pending` /
`task-boundary`, plus the current context % if known. Source the % from a
statusline if shown, or from `~/.anti-hall/auto-handover/<tag>.json`
(`hooks/lib/auto-handover-state.js`'s per-session latch, shared verbatim
with the Claude plugin — `firedPct` is the % it crossed the threshold at;
`<tag>` is the session id from "Session id" below). Use `auto-threshold`
ONLY when that file's `fired` is `true` for this session, or the
auto-handover directive text said so — not just because context "feels
high". `user-request` = the user asked for a handover, or to compact/reset.
`restart-pending` = a restart/new session was mentioned but the threshold
hasn't fired. `task-boundary` = proactive, natural stopping point, nothing
above forced it. This line drives the Terminal declaration below — get it
right.
2. **Goal + definition of done** — one sentence each.
2a. **Session rules (verbatim)** — every instruction the USER issued for this
job (scope limits, "don't X until Y", ordering/serial-only rules, approval
gates), quoted EXACTLY with the turn/date it came from — never paraphrased.
This is the class compaction keeps worst (one study measured 17% of injected
constraints retained — anti-hall repo `https://github.com/talas9/anti-hall/blob/main/docs/KB-handover-research.md`, P2).
Write `none issued` rather than omitting the section. Keep every rule that
is still active in every later seq.
3. **Done + Verified** — with evidence: `file:line`, the command run, and its
actual output/result. Never "tests pass" without the command and a real output
summary.
4. **NOT verified / verification gaps** — mandatory, explicit. If nothing is
unverified, say so explicitly; don't just omit the section.
5. **Open items** — numbered, prioritized; the pending/in-progress subset of
state.md's Task list snapshot, one line each — point at state.md for the
full snapshot.
6. **Decisions summary** — one line each, pointing into `decisions.md` for the
reasoning.
7. **Do-not-repeat summary** — pointing into `trials.md`.
8. **Detail-file pointer table** — one row per detail file: `file · what's inside
· "read this when ..."` — so the next session loads selectively instead of
reading everything.
9. **Predecessor link** — the previous `HANDOVER*.md` in this session, or `none`.
10. **Resume-verification checklist** — concrete steps to run BEFORE trusting
this document: `git status`, `pwd`, re-read `AGENTS.md`, and a smoke/test
command specific to this repo. Directly counters two documented
post-context-reset failures: behavioral rules silently dropped (F1 — hence
the `AGENTS.md` re-read) and stale repo/directory state (F2) —
https://github.com/talas9/anti-hall/blob/main/docs/KB-session-handover.md.
After running it, **append** a `resume-verified: <ISO timestamp> --
<one-line git-status/pwd/smoke summary>` line to this file — this is what
proves the checklist actually ran, not just that it was written down.
`tasklist-guard.js` backs this up mechanically (v0.75.0): when
`handover-resume.js` injected a resume pointer this session and this
session then makes file-changing actions with no `resume-verified:` line
ever landing in the referenced file, one capped Stop-hook nudge fires.
Then the **receiver read-back**: before any new work, tell the user in your
own words (not a paste) the goal, the single next action and every active
session rule, and invite corrections — the incoming side restating the
handover is the step structured clinical handoffs credit with fewer errors
(I-PASS "synthesis by receiver", anti-hall repo
`https://github.com/talas9/anti-hall/blob/main/docs/KB-handover-research.md`, P8/P9).
Everywhere: concrete over vague ("2-space indentation", not "format properly").
Pointers over payloads — reference files/commits/artifacts by path, never inline
large content. Dedup ruthlessly; no narrative padding; no transcript replay (the
single worst format per the KB's own tool survey).
### HANDOVER.md skeleton
```markdown
# Handover — <session-id> · seq <N> · <YYYY-MM-DD>
## Situation
<2-3 lines>
Trigger: <auto-threshold|user-request|restart-pending|task-boundary> · context: <pct%|unknown>
## Next action
<one imperative, executable step>
## Goal + definition of done
<1-2 lines>
## Session rules (verbatim)
- "<exact user wording>" — <turn/date given>; still active: yes
## Done + Verified
- <claim> — evidence: `path:line`, command `<cmd>` → `<real output summary>`
## NOT verified / gaps
- <explicit list, or "none — everything claimed above was verified this session">
## Open items
1. <prioritized>
## Decisions summary
- <one line> → decisions.md
## Do-not-repeat summary
- <one line> → trials.md
## Detail files
| file | contents | read this when |
|---|---|---|
| state.md | ... | ... |
| decisions.md | ... | ... |
| trials.md | ... | ... |
| knowledge.md | ... | ... |
## Predecessor
<path to prior HANDOVER*.md, or "none">
## Resume-verification checklist
- [ ] `git status` — expect: <what>
- [ ] `pwd` — expect: <path>
- [ ] re-read `AGENTS.md` — rules may have been dropped by a context reset
- [ ] `<smoke/test command>` — expect: <result>
- [ ] read-back to the user: goal, next action, active session rules — in your own words, before any new work
resume-verified: <ISO timestamp> -- <one-line git-status/pwd/smoke summary>
```
## Detail-file templates (each also front-loaded, fixed schema)
**state.md** — repo/git/env state:
```markdown
# State — <session-id> seq <N>
Branch: <name> | Clean/dirty: <status> | Last commit: <sha short + subject>
Unpushed: <yes/no, what>
Uncommitted files: <list>
Running processes: <list, or "none">
## Task list snapshot
| id | subject | status | priority | blocked-by |
|---|---|---|---|---|
| ... | ... | pending/in_progress/completed | P0/P1/P2/... | ... |
## Commands run this session (with actual results)
- `<command>` → `<real output, trimmed>`
```
**decisions.md** — append-only, every decision in sequence:
```markdown
## <YYYY-MM-DD HH:MM or seq marker> — <decision title>
What: <the decision>
Why: <reasoning>
Rejected alternatives: <alternative> — <why rejected>
```
**trials.md** — append-only, chronological, includes abandoned attempts:
```markdown
## <what was attempted>
Outcome: <succeeded/failed/abandoned>
Why abandoned (if applicable): <reason>
Do not repeat: <what NOT to try again, and why>
```
**knowledge.md** — KB/docs/research consulted:
```markdown
## <doc/URL path>
What was taken from it: <summary>
Learned facts / gotchas: <list>
Source-of-truth pointer: <yes/no — is this the authoritative source for X>
```
## INDEX.md row format
One row per handover, appended (never rewritten), newest last — same convention
as `.anti-hall/progress/INDEX.md`:
```
- YYYY-MM-DD · <session-id> · seq N · <one-line outcome> · [subsystems] · [main](<date>/<session-id>/HANDOVER.md)
```
## Behavior on invoke
1. Determine session id (a runtime id if available, or sha1-of-transcript-path
fallback, or a stable slug) and today's date.
2. Compute seq = (existing `HANDOVER*.md` count in this session's dir) + 1.
3. Write/update the 5 files: `HANDOVER.md` (or `HANDOVER-N.md`), `state.md`,
`decisions.md`, `trials.md`, `knowledge.md` (seq N>1: apply the carry-forward
rule above first). Detail files are append-only
across a session's multiple handovers (seq 2 appends to seq 1's `state.md`
etc., doesn't overwrite); `HANDOVER*.md` itself is a fresh file per seq.
4. Append the `INDEX.md` row (create `INDEX.md` if it doesn't exist yet).
5. Report to the user EVERY path written this call — the handover directory,
each of the 5 files (`HANDOVER*.md`, `state.md`, `decisions.md`, `trials.md`,
`knowledge.md`), and the exact `INDEX.md` row appended — plus a one-line
summary of what was captured. Don't summarize the paths away; list them.
## Automatic resume
A companion SessionStart hook, `handover-resume.js`, closes the loop: on a
context reset (clear/compaction) or a fresh session start, it scans
`.anti-hall/handovers/` for the newest `HANDOVER*.md` (preferring the SAME
session over a merely newer other-session one) and, if ≤7 days old, injects a
pointer to its path plus the numbered Guided Resume Path — never the file's
content — stating it SUPERSEDES the auto-compact summary and any legacy
`CONTINUE-HERE`-style file. Writing a handover is not just documentation — it
is what the next context actually resumes from.
**Codex compaction resume.** Codex runs `SessionStart` hooks with
`source: "compact"` after it compacts a root session — also when automatic
compaction happens mid-turn, delivering the hook's context to the immediate
continuation (official Codex hooks reference, learn.chatgpt.com/docs/hooks).
`handover-resume.js` is registered on `SessionStart` with no matcher, so it
fires there too.
**PreCompact safety net.** `hooks/precompact-snapshot.js` (registered on Codex's
own `PreCompact` event) writes `PRECOMPACT-<n>.md` into this session's handover
dir right before every compaction: `pwd`, git branch/HEAD/dirty files, a
task-list snapshot when the transcript has one, the last 10 user messages
verbatim (Codex rollout `user_message` events), and a pointer to the newest
`HANDOVER*.md`. Mechanical, never a substitute for this skill, and it never
stops compaction (no stdout, exit 0). The resume hook names it on the next
`SessionStart`.
**Write proactively** — at task boundaries or when a reset is likely, not only
when asked and not at the absolute context-window limit (reset mechanisms can
themselves fail once truly at capacity — https://github.com/talas9/anti-hall/blob/main/docs/KB-session-handover.md, F4).
## Before ending: quiesce, declare, stay honest
**Quiesce gate.** Before declaring safe for a context reset, reach a safe
point: finish/park the current micro-task, enumerate every running
background item (task list, background agents, workflows, monitors), and for
each: await it, stop it, or record it in `HANDOVER.md`'s Open items as STILL
RUNNING with its id and re-attach instructions. While unmet, say WAIT, not
done: `⏳ NOT SAFE for a context reset yet — waiting on: <named items>. I'll
tell you the moment it's safe.`
**The quiesce gate is necessary, NOT sufficient.** "No background agents
running" never by itself makes a reset safe. Declare SAFE (the 🟢 line, "safe
to compact", or `/compact …` / `/new` offered as advice) ONLY when:
- the handover was triggered by the auto-handover threshold
(`Trigger: auto-threshold`), OR
- context is genuinely high — at or near `autoHandover.pct` by the REAL
reading (the rollout's `token_count` / the hook's figure), not a guess.
Never declare it within `guards.compactAdviceRecentTurns` (default 10) turns of
a compaction — context was just reset. Check the actual context % before
saying it. `compact-advice-guard.js` (Stop, shared and registered in Codex's
own `hooks.json`) blocks a violating reply once and names the real %; retract
with one line — `RETRACT SAFE TO COMPACT — <why>` — and continue or stop.
**Terminal declaration is trigger-aware.** Once the quiesce gate is met, the
final message depends on the `Trigger:` line you recorded above:
- `auto-threshold`, OR the user explicitly asked to compact/reset AND
context is genuinely high (at/near the auto-handover threshold): `🟢
**HANDOVER COMPLETE — GOOD POINT FOR /compact OR /new NOW**` + `<saved paths
list>` + `<numbered instructions: trigger the reset; the resume hook guides
the next session>`.
- Any other trigger (`restart-pending`, `task-boundary`, or a user request
to reset) while context is still below the auto-handover threshold: `📝 **Handover saved** (proactive,
context <pct>%): no need to reset now; continue working, or /compact / /new
when you choose.` + `<saved paths list>`.
- Never say "safe for a reset" (the 🟢 line) unless the threshold fired or
context is genuinely high — that line reads as a stop-now signal, and
a proactive save below threshold is not one (field incident: a session below
the 85% auto threshold invoked this skill because a restart was mentioned,
and the old unconditional "✅ HANDOVER COMPLETE — SAFE FOR CONTEXT
COMPACTION/RESET NOW" wording was read as a premature signal to stop).
The declared line is the LAST act of the turn either way; work after it makes
the handover STALE — refresh (same seq, or seq+1) and re-declare before
claiming safe/saved again. `compact-declaration-guard.js` (shared; on Codex
registered for shell commands only; `guards.compactDeclarationGuard`,
default ON since 0.117.0) blocks state-changing shell after a SAFE
declaration in the same turn — regardless of the switch, write
`RETRACT SAFE TO COMPACT — <why>` first
if more work is genuinely needed. `tasklist-guard.js` (shared, and registered in
Codex's own `hooks.json`) backs this up mechanically: file-changing work after
the newest `HANDOVER*.md`'s mtime gets a capped "handover is STALE" advisory
on its Stop output (staleness detection is by mtime + section content, not by
matching either declaration string, so it works the same for both).
## Next-session usage
1. Read `.anti-hall/handovers/INDEX.md` → find the newest relevant row.
2. Open that row's `HANDOVER.md` (or the highest `HANDOVER-N.md` in that
session's directory, if later seqs exist — check its Predecessor chain if
unsure which is newest).
3. Run the Resume-verification checklist BEFORE trusting anything else in the
file, THEN append the `resume-verified:` line to it — `tasklist-guard.js`
nags (once, capped) if file-changing work happens this session without one.
Then give the user your read-back (goal, next action, active session rules,
in your own words) before starting any new work.
4. Page in detail files only as needed, per the Detail-file pointer table's "read
this when" column — progressive disclosure, not a full read of everything.
5. Recreate/reconcile your task list from state.md's Task list snapshot BEFORE
starting any work — the snapshot is the source of truth for what's
pending/in-progress/blocked.