Handoff Skill — bàn giao context & tài liệu sống cho agent
Viết một skill handoff giữ tài liệu sống trong notes/ (progress, handoff log, architecture) và update mỗi lần đổi code, để agent mới resume mà không explore lại. Build từng bước + cách nâng lên global skill.
This is the next part of the Cursor AI Agent series, after Cursor Skills for beginners and Cursor Sub-agents. {Đây là phần tiếp theo của series Cursor AI Agent, sau Cursor Skills cho người mới và Cursor Sub-agents.}
In the sub-agent post there was one easily-missed line: save important output
to a file so it survives when the parent context gets long.
{Ở bài sub-agent có một dòng dễ bị bỏ qua: lưu output quan trọng ra file để
không mất khi context parent dài.}
This post turns that idea into a concrete skill — handoff — that keeps a set
of living docs so every working session can hand off to the next.
{Bài này biến ý đó thành một skill cụ thể — handoff — giữ một bộ tài liệu
sống để mỗi phiên làm việc bàn giao được cho phiên sau.}
1. The problem: context dies between sessions
{Vấn đề: context chết giữa các phiên}
Each conversation with an agent is its own context window. {Mỗi conversation với agent là một context window riêng.} When you close the chat or it resets because the window filled up, everything it learned — the structure, what each file does, what was decided and why — disappears. {Khi bạn đóng chat hoặc nó reset vì context đầy, mọi thứ nó học được — cấu trúc, file nào làm gì, đã quyết định gì và vì sao — biến mất.}
Session 1: explore 30 files → understand → 60% done → out of context
│
▼ (close chat / reset)
Session 2: "Wait, what is this project?" → explore 30 files again → ...
You pay tokens twice for the same “understand the codebase” work, and worse: session 2 may decide differently because it doesn’t know why session 1 chose what it chose. {Bạn trả token 2 lần cho cùng việc “hiểu codebase”, và tệ hơn: phiên 2 có thể quyết định khác vì không biết lý do của quyết định cũ.}
The fix is not a bigger context window. It is writing state out of the context — into files — so the next session reads it back. That is handoff. {Giải pháp không phải context to hơn, mà là ghi state ra ngoài context — vào file — để phiên sau đọc lại. Đó là handoff.}
2. From “save a file” to a living doc system
{Từ “lưu một file” tới một hệ tài liệu sống}
A single notes.md rots fast. The trick is to split docs by how often they
change and to update them on every code change, not just at the end.
{Một file notes.md đơn lẻ mục rất nhanh. Mẹo là tách tài liệu theo tần
suất thay đổi và update mỗi lần đổi code, không phải chỉ lúc cuối.}
notes/
├── progress.md # status table — what's done / doing / next
├── handoff.md # chronological log — date+time, files, what/next
├── architectures.md # the map — structure + links to split docs
├── getting-started.md # setup / run / build (optional)
├── frontend-architecture.md # component & layout tree (optional)
├── content-architecture.md # data layer / schemas (optional)
└── {feature-name}.md # one file per LARGE feature
working.md (at the repo root) stays as a lightweight “current vs previous
request” scratch. Everything durable lives in notes/.
{working.md (ở gốc repo) là scratch nhẹ “request hiện tại vs trước đó”. Mọi
thứ bền vững nằm trong notes/.}
3. The two docs that do the heavy lifting
{Hai file gánh phần nặng nhất}
progress.md and handoff.md answer two different questions.
{progress.md và handoff.md trả lời hai câu khác nhau.}
| File | Question it answers | Shape |
|---|---|---|
progress.md | ”Where do things stand now?” | A status table |
handoff.md | ”What happened, when, and why?” | A chronological log |
progress.md is the current state — overwrite freely, keep it short.
{progress.md là trạng thái hiện tại — ghi đè thoải mái, giữ ngắn.}
handoff.md is the history — append-only session entries, each with an
exact date and time, the files changed, what was done, and what’s next.
{handoff.md là lịch sử — append từng phiên, mỗi entry có date+time chính
xác, file đã đổi, đã làm gì, làm tiếp gì.}
Keeping history out of progress.md is what stops it from bloating — the trap
that made the old single-file approach useless.
{Tách lịch sử khỏi progress.md chính là cái giữ nó không phình — đúng cái
bẫy khiến cách 1-file cũ thành vô dụng.}
4. Why notes/ and not .cursor/
{Vì sao là notes/ chứ không phải .cursor/}
This is deliberate: notes/ is project documentation, not tool config.
{Đây là quyết định có chủ đích: notes/ là tài liệu của project, không
phải config của tool.}
- Humans read it too — a new dev opens
notes/architectures.mdand gets the system without an agent. {Con người cũng đọc — dev mới mởnotes/architectures.mdlà hiểu hệ thống mà không cần agent.} - It is tool-agnostic — switch away from Cursor and
notes/still holds value;.cursor/is tied to one tool. {Nó độc lập với tool — đổi khỏi Cursor thìnotes/vẫn còn giá trị;.cursor/thì gắn chặt một tool.} - Commit policy is yours — commit
notes/as shared team memory, or gitignore it as scratch. Either works. {Quyền commit là của bạn — commitnotes/làm “bộ nhớ chung”, hoặc gitignore nếu coi là scratch. Đều được.}
Convention: every project uses ./notes/, so the skill only ever needs to
know one path.
{Quy ước: mọi project dùng ./notes/, nên skill chỉ cần biết một đường
dẫn duy nhất.}
5. The key rule: update on EVERY change
{Quy tắc cốt lõi: update MỖI lần đổi code}
The skill does not wait for “save progress”. It triggers after any meaningful edit: {Skill không đợi tới lúc “save progress”. Nó kích hoạt sau mỗi edit đáng kể:}
- Implementing or modifying a screen / route / component {Làm hoặc sửa một screen / route / component}
- Adding or changing an API endpoint or data model {Thêm hoặc đổi API endpoint hoặc data model}
- Changing dependencies, config, or any architecture {Đổi dependency, config, hoặc bất kỳ kiến trúc nào}
Why so aggressive? Because docs written “later” are never written. Tying the update to the edit keeps them true. {Vì sao gắt vậy? Vì tài liệu để “viết sau” thì không bao giờ được viết. Gắn update vào edit giữ chúng luôn đúng.}
6. Build the skill step by step
{Build skill từng bước}
Following the four phases: Discovery → Design → Implementation → Verification. {Theo 4 phase: Discovery → Design → Implementation → Verification.}
Phase 1 — Discovery
Answer five questions. {Trả lời 5 câu.}
- What does it solve? Hand off state between sessions and keep docs current. {Giải quyết gì? Bàn giao state giữa các phiên và giữ tài liệu luôn mới.}
- Personal or project? Project first (
.cursor/skills/handoff/); promote to global later. {Personal hay project? Project trước; nâng lên global sau.} - When should it load? On resume, and after any code change. {Khi nào load? Lúc resume, và sau mỗi lần đổi code.}
- Special output? Yes — the
notes/doc set + templates. {Output đặc biệt? Có — bộ docnotes/+ template.} - Existing pattern? Workflow Pattern (read → work → write loop). {Pattern sẵn? Workflow Pattern (vòng read → work → write).}
Phase 2 — Design
The description decides whether the skill ever triggers. Third person, WHAT +
WHEN, stuffed with trigger terms:
{description quyết định skill có được trigger không. Ngôi thứ ba, WHAT +
WHEN, nhồi trigger terms:}
description: Maintain living project docs in notes/ and hand off between sessions. Update docs on EVERY code change (new screen, feature, flow, bug fix, schema, architecture) and read them first on resume. Use when implementing, modifying, fixing, refactoring, resuming, saving progress, or updating notes.
Phase 3 — Implementation
Directory layout, references one level deep: {Cấu trúc thư mục, references chỉ 1 cấp sâu:}
.cursor/skills/handoff/
├── SKILL.md
├── progress-template.md
├── handoff-template.md
└── architecture-template.md
The core of SKILL.md — the trigger list, the doc set, and the per-change
steps:
{Phần lõi của SKILL.md — danh sách trigger, bộ doc, và các bước mỗi lần đổi:}
---
name: handoff
description: Maintain living project docs in notes/ and hand off between sessions. Update docs on EVERY code change ... Use when implementing, modifying, fixing, resuming, saving progress, or updating notes.
---
# Handoff
## When to trigger
Update docs after: implementing/modifying a screen, changing an endpoint or
schema, adding components, changing auth, deps, or any architecture.
Read docs first when resuming or starting a non-trivial task.
## Steps on every change
1. Identify what changed (files created/modified/deleted; large feature?).
2. Update `notes/progress.md` (status table: ✅ / 🟡 / ⬜).
3. Update `notes/handoff.md` (session entry: date+time, files, what, next).
4. Update architecture docs only if structure changed.
5. Update `working.md` at repo root (current vs previous request).
## If notes/ is missing
Bootstrap from templates: progress-template.md, handoff-template.md,
architecture-template.md.
The handoff.md session-log template is the new piece compared to v1:
{Template session-log handoff.md là phần mới so với v1:}
## Session N — May 29, 2026, 10:15
### What was done
1. [First thing]
2. [Second thing]
### Files changed
- `path/to/file` — what changed
### What's next
- [ ] [Next task]
Phase 4 — Verification
-
SKILL.mdunder 500 lines. {SKILL.mddưới 500 dòng.} - Description is specific, third person, full of trigger terms. {Description cụ thể, ngôi thứ ba, nhiều trigger terms.}
- References one level deep (
SKILL.md→ templates, no deeper). {References 1 cấp sâu (SKILL.md→ template, không sâu hơn).} - Test it: open a new chat, say “resume where we left off”, check it reads
notes/first. {Test thật: mở chat mới, gõ “resume where we left off”, xem nó có đọcnotes/trước không.}
7. Large features get their own file
{Feature lớn được file riêng}
Don’t bloat a main doc with a 200-line feature write-up. For a major feature
(new module, new page group, major flow), create notes/{feature-name}.md and
add a reference link from the main doc.
{Đừng nhồi 200 dòng mô tả feature vào doc chính. Với feature lớn (module mới,
nhóm page mới, flow lớn), tạo notes/{feature-name}.md rồi thêm link tham
chiếu từ doc chính.}
Rule of thumb: split it out when it would add more than ~50 lines to an existing doc, or when it’s a self-contained area (an admin panel, a payment integration, an OAuth setup). {Quy tắc: tách ra khi nó thêm hơn ~50 dòng vào doc có sẵn, hoặc khi nó là một mảng độc lập (admin panel, payment, OAuth setup).}
8. Using it in practice
{Dùng trong thực tế}
Resume flow
Open a new chat in a repo that already has notes/ and say:
{Mở chat mới trong repo đã có notes/ và gõ:}
Continue working on this project.
The agent reads notes/progress.md + handoff.md + architectures.md first,
then says what’s left and picks up — no re-exploring 30 files.
{Agent đọc notes/progress.md + handoff.md + architectures.md trước, rồi
nói còn gì và làm tiếp — không explore lại 30 file.}
Update flow
After a chunk of work, or when context feels full: {Sau một mảng việc, hoặc khi thấy context sắp đầy:}
Update the notes and hand off.
It appends a handoff.md entry (with timestamp + files changed), refreshes the
progress.md table, and touches any architecture doc whose area changed.
{Nó thêm một entry handoff.md (kèm timestamp + file đã đổi), làm mới bảng
progress.md, và đụng vào doc architecture nào có vùng thay đổi.}
Live demo on this blog
{Demo sống trên blog này}
This repo already runs the convention: {Repo này đã chạy đúng quy ước:}
notes/
├── progress.md # status table of blog tasks
├── handoff.md # session log (this post was written across sessions)
├── architectures.md # blog map → links to the split docs below
├── getting-started.md
├── frontend-architecture.md
└── content-architecture.md
9. Promote to a global skill
{Nâng lên global skill}
Once it works in one project, reuse it everywhere by copying it to the personal scope: {Khi đã chạy ổn ở một project, dùng lại ở mọi nơi bằng cách copy sang scope personal:}
cp -r .cursor/skills/handoff ~/.cursor/skills/handoff
| Scope | Path | Who uses it |
|---|---|---|
| Project | .cursor/skills/handoff/ | Anyone who opens this repo (via git) |
| Personal | ~/.cursor/skills/handoff/ | Every project on your machine |
Nothing else changes — the skill always writes to ./notes/ relative to the
open project, so the same convention applies everywhere.
{Không cần sửa gì — skill luôn ghi vào ./notes/ tương đối theo project đang
mở, nên cùng quy ước áp dụng ở mọi nơi.}
Never put it in
~/.cursor/skills-cursor/— that folder is for Cursor’s built-in skills and may be overwritten on update. {Đừng để trong~/.cursor/skills-cursor/— folder đó dành cho skill built-in của Cursor, có thể bị ghi đè khi update.}
10. Anti-patterns
{Anti-patterns}
Putting history in progress.md. It bloats. History belongs in handoff.md;
progress.md only shows the current state.
{Nhét lịch sử vào progress.md. Nó phình. Lịch sử thuộc về handoff.md;
progress.md chỉ hiện trạng thái hiện tại.}
A play-by-play of every edit. Record decisions and why, not “changed line 42”. The diff already tells what changed. {Kể từng dòng edit. Ghi quyết định và vì sao, không phải “sửa dòng 42”. Diff đã kể cái gì đổi rồi.}
architectures.md as a changelog. It describes current structure; git is
the changelog.
{architectures.md thành changelog. Nó mô tả cấu trúc hiện tại; git mới
là changelog.}
Writing but never reading. The loop starts with read. If the agent jumps
into exploring, tell it to read notes/ first.
{Ghi mà không đọc. Vòng lặp bắt đầu bằng read. Nếu agent nhảy vào
explore, nhắc nó đọc notes/ trước.}
References nested too deep. SKILL.md → a.md → b.md: the agent may not
read that far. Keep it one level.
{References lồng quá sâu. SKILL.md → a.md → b.md: agent có thể đọc
không tới. Giữ 1 cấp.}
Summary
{Tổng kết}
The handoff skill turns the agent’s memory from ephemeral (dies with the
context window) into persistent (lives in notes/):
{Handoff skill biến “bộ nhớ” của agent từ ephemeral (chết theo context
window) thành persistent (sống trong notes/):}
- Split by change rate:
progress.md(now),handoff.md(history),architectures.md(structure). {Tách theo tần suất đổi:progress.md(hiện tại),handoff.md(lịch sử),architectures.md(cấu trúc).} - Update on every change, not “later”. {Update mỗi lần đổi code, không để “lúc sau”.}
- Large features get their own file, linked from the main doc. {Feature lớn được file riêng, link từ doc chính.}
notes/is documentation, usable by humans and any tool. {notes/là tài liệu, dùng được cho con người và mọi tool.}- Project first, global later — review via git, then
cpto~/.cursor/skills/. {Project trước, global sau — review qua git, rồicpsang~/.cursor/skills/.}
Start by adding notes/progress.md and notes/handoff.md to the project you’re
most deep in — the next agent session will “remember” instead of asking you from
scratch.
{Bắt đầu bằng cách thêm notes/progress.md và notes/handoff.md cho project
bạn đang làm dở nhất — phiên agent kế tiếp sẽ “nhớ” thay vì hỏi lại bạn từ
đầu.}