# Ctx Takeover

> Take over a case in a fresh session — use on "take over C-07", "continue that case", or /ctx-takeover C-NN; reads only the case file (old transcripts off-limits), signs as pen-holder, recites goal, case, progress and next step for your spot-check. Also triggers on Chinese — 开新会话继任时用：用户说"接手 C-07""继续那个案""你来接这个案""接着上个会话的活"，或显式 /ctx-takeover C-NN。

- Skill: `bestiaya/ctx-takeover` (Agent Skill)
- Install (CLI): `npx skillmds@latest add bestiaya/ctx-takeover`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bestiaya/ctx-takeover/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: bestiaya (https://skillmd.com/u/bestiaya)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/bestiaya/ctx-takeover

---


# Takeover: read the case only → sign → recite

> **Speak the user's language, and write the case file / board / inbox in it.** Section letters A~I and this vocabulary are fixed bilingual: status **awaiting takeover** (候接手) / **in discussion** (讨论中) / **awaiting decision** (候拍) / **closing (do not take)** (收口中(勿接)) / **closed** (已收口) / **running** (在跑) / **awaiting acceptance** (待验收) / **queued** (排队) / **to dispatch** (待派) / **delivered** (已交货) / **done** (已完); header fields `status` (状态) / `pen-holder` (持笔) / `stint` (任期) / `updated` (更新), and `predecessor retired` (前任已退役); roles `lead` (导师) / `exec` (执行).

The argument = a case number (`C-07`, say) or a case file path.

## 1. Locate
Given a path, use it. Given a case number, glob `<case number>*.md` in **this project's** case library, never another project's. Project root = the git root if there is a `.git`, else cwd; library = the path on the `ctx-kit case library: <path relative to the project root>` line in the project root's `CLAUDE.md`, else an existing `_ops/CASES/`, else `cases/`. **Resolve it yourself before asking.** 0 hits: list the directory and ask which, **never guess**. More than one: list the candidates and ask.

## 2. Read the case file only, and only the sections you should
**Never read any old session transcript (jsonl)**, the paths in section G included — G is reference only, fetched once, on target, when the question in front of you plainly needs it. **Never `cat` the whole case file**: E has no length limit and old rows run to paragraphs, so a long case read whole spends most of its characters on rows nobody will look at. Run the loader instead — header line + A~D whole + E's header, its rows at running / awaiting acceptance / queued / to dispatch and the newest delivered row's verdict + the inbox's undisposed rows in full and the last three disposed ones, with F / G / H as a name and a line count. It finds columns by header text and prints the characters loaded on its last line.

```bash
S="${CLAUDE_PLUGIN_ROOT:+$CLAUDE_PLUGIN_ROOT/scripts/takeover-load.py}"; [ -f "$S" ] || S="$HOME/.claude/scripts/takeover-load.py"
if [ -f "$S" ]; then python3 "$S" <case file path>; else echo "takeover-load.py is in neither place ctx-takeover looks (plugin root, then ~/.claude/scripts/) — nothing loaded. Copy scripts/takeover-load.py out of the ctx-kit repository into ~/.claude/scripts/, as the README manual-install step says."; fi
```

Those two places in that order, as `ctx-checkup` §1 does; never type a plugin path by hand. Where it says the script is in neither, **say exactly that — nothing was loaded**, pass on that one fix, and never recite off a case you did not load. **Run it with a real python3**: an `xcodebuild` error means the interpreter resolved somewhere else (the macOS Xcode shim), not that the script is broken.

**The inbox must be read, never skipped**: other cases' messages and your predecessor's to-dos live there, and an empty disposition cell means it waits on you (measured: 6 items in, 3 starred, and a successor who skipped §I lost the lot). **Write every disposition opening with done (已办) / dropped (不办) / moved to (已转)** — nothing reads past the opening — and escape a pipe in your own text as `\|`. **Do not read deliverables end to end to be "thorough"**; fetch on target.

**The session name in an inbox row says who wrote it — it is not an address.** Answering a row, or delivering into another case, is **one indivisible sequence, six steps without a break**:

1. **Any address read earlier is void**, however few minutes ago; anything in between and you restart at step 2.
2. Read the **target case file's** header-line **Pen-holder** cell now — that cell alone gives the session name / id.
3. **Immediately before sending**, `get_session` (or `list_sessions`) on that session and read it at this moment. A retired session is not unreachable — the send goes through and wakes it — so this comes before the send, never after.
   **3b, with the list already up: is that cell out of date?** It is hand-written, so it can name a session that is alive and no longer on this case. Filter `list_sessions` to this project's working directory and titles matching `^(?:✕\s*)?(?:(\d+)-CNN|CNN-(\d+))` — `CNN` = this case's number with the hyphen out (`C-07`→`C07`), letters literal, digits the case's own; **the stint number sits behind the case number by §3's rule**, and the other alternative catches titles set before a project changed to it. Drop everything carrying `✕` or `isArchived` and take the **latest**: a `CNN-NN` title is later than any `NN-CNN` one, and inside one form the larger number is later. Not the cell's session → the cell names an earlier stint: send to the latest and say one line, "the case header names an earlier stint, 03-…; sent to C07-22 instead". **This redirects the address; it is not a fourth refusal condition**, and finding nothing here means you say nothing and go on with the cell as written.
4. **Refuse to send if any one of these holds**: the title opens with `✕` (the retirement mark); `isArchived` is set; the Pen-holder cell names nobody live (awaiting takeover / closing / predecessor retired). **All three are asked of the address 3b left you, not of the cell as written**: where 3b found a live session of this project titled for this case, somebody is live on it and the cell is merely unsigned, so send there and say the header names an earlier stint; where 3b found nothing, the cell is all there is and the third condition stands.
5. **Where you refused**: append one row to the target case's §I inbox (append only, never touch the body) and say one line to the owner then and there — "that case has no live pen-holder / has retired; do you want a session opened to take it?"
6. **Only once all of it passes, send.** **Addressing goes by title plus working directory** (that pair works from a bare terminal); the session id is what a session **signs** with and what breaks a tie between two of one title.

**A `✕` noticed only afterwards, on a reply that comes back, means it has already gone astray** — the symptom of skipping 3 and 4, never a substitute for them. Send again to whoever the header names, and tell the owner in one line.

**Size limit**: the loader's last-line count = the entry tax base, in three bands — **≤10,000 green; >10,000 and ≤15,000 yellow, slimmed at the next close-out; >15,000 must be slimmed before the case changes hands**. Characters, not bytes and not file size.

**Cross the line during your own stint and you slim it yourself, there and then**, never left for the successor: whoever wrote those rows is the only one who can tell at a glance what is safe to move. **A load already past red when you take over is a red case your predecessor left you** — slim it here, before you sign. The five steps are **`ctx-handoff` §3's**, with two changes: of the steps that move rows, do only the **verbatim** move into the archive file now, and **leave rewriting B, and moving decisions into C, until after your recite has been spot-checked** (both are judgements about a case you have not yet recited). **Commit the new archive files in the same breath**, in the repository the case file itself is in (§6) — until then the pointer left in the case leads nowhere for anybody else, and the rows it points at are on one disk only. Then say in the recite that you took over a red case, and what you moved.

## 3. Sign (the only signal that the handover is complete)
- Status **『closed』**: **do not sign, do not recite**; reply "this case is closed; to reopen it say 'reopen C-NN'". **Reopening** = status back to `awaiting takeover`, one line in F ("reopened: <why>"), then take over as below.
- Status **『closing (do not take)』**: do not sign, do not recite; reply "this case is being closed out, take it later". Only when 『updated』 is stale (>1 day), or the user confirms the closing session is dead, may you force it — say "what I am taking is a half-closed case" and sweep B~H for gaps before reciting.
- **A pen-holder already there that is not this session → warn before anything else**: "the pen-holder of this case is X, another session may be taking it over, and two takers will tear the books apart"; change it only once the user confirms. (Status `awaiting takeover` with the pen-holder marked "predecessor retired" is not a double takeover — sign straight away.)
- **Title**: one the owner set by hand (not the system's auto-generated summary form) → **keep it**. Otherwise `set_session_title` to **`C<NN>-<SS> <case short name>-<what this stint does>[-exec]`** — `C07-03 billing-async-vs-streaming-decision`; 中文 `C07-03 计费-异步还是流式的决策`:
  - **`C<NN>`** = the case number with its hyphen out (`C-07`→`C07`). **`<SS>`** = the stint number, **read off the header line's `stint` (任期) field and nowhere else**: add 1 to what stands there and write the new number back as you sign. **Never call `list_sessions` for a number** — the project-wide counter this replaces cost 11,000–17,000 characters of session list on every takeover, and had collided twice anyway. Both parts are written two digits wide; a project numbering past 99 runs wider.
  - **No `stint` field there** (a case opened before this rule): this takeover is `01`. Write `stint: 01` (`任期: 01`) onto the header line and say one line — "the stint count starts here; earlier ones are in the chronicle" — rather than counting old titles or asking the session list.
  - **Case short name**: off the board's Name cell, where it stands as `(short name: X)` / `〔短名：X〕`, fixed once when the case was opened; never coin a second. **A Name cell carrying none (a board older than short names) is the one exception**: coin one off the case name — two to four characters, one word in English, by `ctx-kickoff` §2 — **write it into that Name cell as you sign** (this holds even where you kept the owner's title), so it is coined once and every later session reads it off the board; then say **"the short name X is one I picked, change it if you want"**.
  - **A one-off has neither case number nor short name**: `C00-<nn>`, then what this stint does — `<nn>` being the number of its row in the board's one-offs table, which is the number `ctx-kickoff` gave it when it triaged the job.
  - **The last segment says what this stint is doing, not the case name.** **`-exec` only on a dispatched execution session**; **no project prefix** unless two projects genuinely collide (`ck-C07-03 billing-…`).
  - **Old titles are never renamed**: this form applies from the next stint on, and a session already running as `NN-C07short-…` keeps its name.
  - Tool missing or the call fails: skip it, say "the UI title is not in sync", and change the pen-holder anyway.
- Set the header line's **pen-holder** to that name (`name @<first 8 of the session id>` where you can get it), its **stint** to the number you just used, and **updated** to today. **Which id: the `sessionId` that `get_session` / `list_sessions` hand back** — `local_<uuid>`; on the desktop app, `get_session` on `self`. **Never sign with the transcript file's name** under `~/.claude/projects/<project>/`: a second id for the same session, minted a second apart, matching no live session anybody can list. **Cannot get it → write the title alone**, not a required field. Write the same name into the Pen-holder cell of this case's board row.
- **Later, if what this stint is mainly doing genuinely changes, rename**: the new title, then the case header's pen-holder cell and the board row's Pen-holder cell in the same move — three places, one name.

## 4. Recite in four chapters (proof that you caught it, and that the goal chain is in hand)
**One layer to a chapter, three to five lines each**; the criterion = the person involved recognises it from memory at a glance. Do not recite the whole case, and **raise no improvement suggestions here**.

1. **The top-level goal and where this case sits**: the top-level goal in one sentence / the pain in the **moment scenario** — the moment it hurts, in the words the people involved use — and the assets it needs / **the milestone tag, off the Milestone cell of its board row (or `milestone: M?` in A's R field), quoting that milestone's own "what is true once it is reached" line** / what pulls it from upstream, off the board header; with no board header use A's R field and suggest building one. A tag reading `candidate milestone` is recited as exactly that and put to the owner: add a plan row, or stop the job. **The last sentence answers which link of the top-level goal this case is pushing right now, and whether it is still aligned.**
2. **This case's goal and route**: why it was opened → what it is answering now / the directions the owner has already decided / a **route step table**: step · what it does · which goal it serves · status.
3. **Current progress**: for the **running / awaiting acceptance** rows, **check the real state on the ground before reporting** — dispatch records, processes, artifact timestamps, the liveness command your predecessor left on the E row or in H; **never copy the point-in-time status off the case file** (measured: six sessions dispatched at 20:38, the case honestly said "running", and all six had finished twelve hours before the successor reported them as running). **The same check covers D**: an item already answered on the ground is settled whatever the case says, so report it as "done on the ground, not yet cleared from the case" and clear the row once the owner confirms.
   **One table for the most recent experiment, only if there is one** — where the case is not experimental or has none, **leave the table out entirely**: no empty table, no "none" row. Columns: what question it answers / how it is tested / what counts as a pass / expected vs actual and the verdict / **conclusion: what it means for the goal**.
   Then a **one-line ledger reading** (how many active E rows and in what statuses + the newest delivered verdict, or the current M metric; the number where there is one, plainly so where there is none) + **one line for the inbox** — N undisposed and the most pressing, or "nothing outstanding in the inbox".
4. **Next step, derived from the conclusion**: an **ordered table** — order · what to do · **which conclusion it rests on** · which goal it serves · who it waits on; items awaiting decision or on hold listed separately.

## 5. Wait for the spot-check
One last sentence: **I am waiting for your spot-check questions; once I pass, I will carry on with this case.** Under spot-check: in the case → answer directly, naming the section; not in the case → **say "it is not in the case" first**, then fetch once, on target, following G / H, naming the source; cannot fetch → say you cannot. **Never invent, never fill it in from imagination, never patch the gap with common sense** — one spot-check question is a negative control aimed at exactly this.

## 6. The first moves after taking over
**First check whether your predecessor's changes actually got committed** — case file, board, the artefacts the case points at — and where they did not, find out whether that work is still in flight or was simply forgotten, before building on it. **Ask the repository the case file is in, not the one you are standing in**: `git -C <case library directory> rev-parse --show-toplevel` names it, and the check runs inside that directory. A case library kept as its own repository nested inside the project's is an ordinary shape, and **a clean `git status` in the outer repository says nothing whatever about the inner one** (measured twice in one day; both successors read the outer one as clean and both were wrong).

Then pick "write to disk as you discuss" back up: section C the moment a decision is made, section B the moment the plan changes; when dispatching, pick the carrier by the dispatch criteria; once this session is **both** past the yellow line (400k by default) and at a batch boundary — or the moment it is past red — **only remind** the owner with the current watermark reading, and only the first time you cross into a band. Whether to close out is the owner's call, and **never run ctx-handoff on your own initiative**.

