
Agent Handoff
- 31 installs
- 1 repo stars
- Updated June 1, 2026
- wecansync/agent-skills
agent-handoff is an agent skill that keeps `.ai/` context synchronized across agents—usable whenever a solo builder needs continuity before committing to more work.
About
agent-handoff is an always-on coordination skill for projects where more than one AI agent touches the codebase over time. Each session has isolated chat history; the `.ai/` directory holds PROJECT, PATHS, PLAN, HANDOFF, LOG, and dated session files so the next agent does not re-discover architecture or repeat finished work. On every conversation start you must read the four core context files before doing work; if anything is missing or still has installer placeholders, you repair the handoff system first. Before ending any response you complete write-back—at minimum LOG, and HANDOFF plus a session file when you changed files, ran tests, investigated, planned, or decided something. Solo builders running Claude Code, Cursor, or Codex in parallel benefit because handoff turns episodic agents into a sequential team without a human relay.
- Mandatory read on every conversation start: `.ai/PROJECT.md`, `.ai/PATHS.md`, `.ai/PLAN.md`, `.ai/conversations/HANDOFF.
- Write-back before finishing every response: append LOG; update HANDOFF and session files when files, tests, plans, or de
- Repairs missing or placeholder `.ai/` structure by scanning the project against skill reference templates
- Requires real environment timestamps (`date`) for session paths—no inferred dates from model memory
- Version marker `agent-handoff:v3` for always-active multi-agent continuity
Agent Handoff by the numbers
- 31 all-time installs (skills.sh)
- +1 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #9,202 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wecansync/agent-skills --skill agent-handoffAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 31 |
|---|---|
| repo stars | ★ 1 |
| Security audit | 3 / 3 scanners passed |
| Last updated | June 1, 2026 |
| Repository | wecansync/agent-skills ↗ |
What it does
Bridge isolated agent sessions with a shared `.ai/` handoff so every conversation starts informed and ends with LOG, HANDOFF, and session files updated.
Who is it for?
Best when you're alternating agents or long-running repos where work spans many chat sessions and needs shared PLAN and blocker state.
Skip if: Single-session one-off prompts with no `.ai/` convention, or teams that already enforce identical handoff via another locked system they will not duplicate.
When should I use this skill?
Always active: on every conversation start before work and before finishing every response that touched the project.
What you get
The next agent reads current PROJECT, PATHS, PLAN, and HANDOFF state and your session leaves an auditable LOG and HANDOFF trail under `.ai/conversations/`.
- Updated `.ai/conversations/LOG.md`
- Updated `.ai/conversations/HANDOFF.md`
- Session file under `.ai/conversations/sessions/YYYY-MM-DD/` when applicable
By the numbers
- 4 mandatory read files on every conversation start
- Handoff spec version agent-handoff:v3
Files
Agent Handoff — Bootstrapper & Manager
This skill bootstraps and maintains the .ai/ shared context directory that enables seamless handoff between AI agents (Claude, Codex, Gemini, Cursor, Windsurf, OpenCode, Copilot, and others).
The always-active read/write behavior is handled by the snippet injected into each agent's config file (CLAUDE.md, codex.md, .cursorrules, etc.) during installation. This skill handles the heavier operations: first-run bootstrapping, stale detection, and project scanning.
For file format templates, see references/templates.md. For real-world examples, see references/examples.md.
---
When This Skill Triggers
- User says "agent handoff", "handoff", "bootstrap", "initialize", "set up handoff", "set up agent context"
- User says "continue", "resume", "keep going", "what was the last agent doing"
- Any core
.ai/file is missing, empty, or still has installer placeholders:
.ai/PROJECT.md, .ai/PATHS.md, .ai/PLAN.md, .ai/conversations/HANDOFF.md
- HANDOFF.md is stale (>7 days since last update)
- User asks about session files, missing handoff writes, or another agent not
invoking the handoff flow
- User explicitly invokes
/agent-handoff
---
First-Run Bootstrapping
Run the full bootstrap if any required file is missing, empty, or placeholder-only:
.ai/PROJECT.md.ai/PATHS.md.ai/PLAN.md.ai/conversations/HANDOFF.md
Placeholder examples include Last updated: —, (empty), "created (empty, will be populated on first agent run)", or files with only a heading.
Step 1: Create directory structure
mkdir -p .ai/conversations/decisions .ai/conversations/sessions
mkdir -p ".ai/conversations/sessions/$(date +%F)"Step 2: Detect project type and tech stack
Read all package manifests that exist (a polyglot project may have several):
composer.json— PHP (Laravel, Symfony, etc.)package.json— Node.js / frontend (Next.js, Nuxt, React, Vue, Angular, etc.)Gemfile— Ruby (Rails, Sinatra, etc.)requirements.txt/pyproject.toml/Pipfile— Python (Django, Flask, FastAPI, etc.)go.mod— GoCargo.toml— Rustpom.xml/build.gradle— Java / Kotlin*.csproj/*.sln— .NET
Read all agent/convention configs that exist:
CLAUDE.md,AGENTS.md,.cursorrules,.windsurfrules,codex.md,GEMINI.mdREADME.md,CONTRIBUTING.md.editorconfig, lint configs (.prettierrc,eslint.config.*,phpcs.xml, etc.)
Read environment hints:
.env.example— expected environment variablesdocker-compose.yml/Dockerfile— containerized setupMakefile/justfile— common commands
Step 3: Discover documentation
Scan these locations for documentation files:
Root: *.md files (README, CHANGELOG, CONTRIBUTING, ARCHITECTURE, etc.)
Docs: docs/ documentation/ wiki/ guides/ .github/
Specs: specs/ spec/ plans/ rfcs/ adrs/ design/ proposals/
API: docs/api/ api-docs/
openapi.yaml openapi.json swagger.json swagger.yaml
*.postman_collection.json (up to 3 levels deep)
insomnia*.json insomnia*.yaml
Nested: docs/archive/ docs/plans/ any docs/ subdirectory with markdownFor each location found:
find {dir} -maxdepth 3 -type f \( -name "*.md" -o -name "*.pdf" -o -name "*.postman_collection.json" -o -name "openapi.*" -o -name "swagger.*" \)Classify by reading the title or first 10 lines:
| Category | Examples | Priority |
|---|---|---|
| Requirements | TRD, PRD, BRD | HIGH — read before implementing |
| Architecture | System design, ADR | HIGH |
| Implementation Plans | Roadmap, phasing doc | HIGH |
| Project Overview | Overview, project brief | HIGH |
| Operational Guides | User guides, runbooks | MEDIUM |
| API Documentation | Integration guides, OpenAPI | MEDIUM |
| Feature Specs | Per-feature specs, RFCs | ON-DEMAND |
| Archived | Anything in archive/ or older version | LOW |
Version detection: When multiple versions exist (e.g., TRD-v3, TRD-v4, TRD-v5), identify the current version by highest number or most recent date. List only the current version under "Reference Documents (current)." Older versions go to "Archived."
Step 4: Detect spec/plan directory patterns
If specs/, rfcs/, adrs/, or similar directories exist: 1. List all subdirectories 2. Pick one representative and list its contents 3. Document the detected pattern (what files each entry contains) 4. List all entries with one-line descriptions 5. Identify active vs completed (check git history or task checkboxes)
If no formal spec system exists, note how the project tracks work (GitHub Issues, Jira, informal, etc.) if detectable.
Step 5: Generate context files
Using the templates in references/templates.md, generate:
.ai/PROJECT.md— from detected stack, architecture, and key documents.ai/PATHS.md— from discovered files and documentation.ai/PLAN.md— from active work (git branch, recent commits, spec status).ai/conversations/HANDOFF.md— initial state with "system initialized" note.ai/conversations/LOG.md— header only
Use the real local system time for all dates. On Unix-like systems, get it with:
date '+%Y-%m-%d %H:%M %Z'
date '+%Y-%m-%d/%H%M%S'Never copy a date from old project docs, model memory, or previous handoff entries when creating new log/session records.
Step 6: Inject always-active snippet into agent config files
The .ai/ files are useless unless agents actually read them. This step ensures every agent's config file contains the always-active snippet that drives the read-on-start / write-after-task behavior.
Read the snippet from inject.md (same directory as this SKILL.md file — check .claude/skills/agent-handoff/inject.md or .agents/skills/agent-handoff/inject.md).
For each agent config file below, check if it already contains the marker ## Agent Handoff (always active). If NOT present, append the full snippet. If already present, skip it.
| Agent | Config file | When to inject |
|---|---|---|
| Claude Code | CLAUDE.md | Always — create the file if it doesn't exist |
| Codex (OpenAI) | codex.md | Always — create the file if it doesn't exist |
| Multi-agent / Antigravity | AGENTS.md | Always — create the file if it doesn't exist |
| Cursor | .cursorrules | Only if the file or .cursor/ directory exists |
| Windsurf | .windsurfrules | Only if the file exists |
| Gemini CLI / older Antigravity | GEMINI.md | Only if the file exists or .gemini/ exists |
| OpenCode | .opencode/instructions.md | Only if .opencode/ directory exists |
| GitHub Copilot | .github/copilot-instructions.md | Only if .github/ directory exists |
If `inject.md` is not found, use this minimal fallback snippet instead:
## Agent Handoff (always active)
<!-- agent-handoff:v3 -->
ON EVERY CONVERSATION START, read these files:
1. .ai/PROJECT.md
2. .ai/PATHS.md
3. .ai/PLAN.md
4. .ai/conversations/HANDOFF.md
If any are missing, empty, or placeholder-only, bootstrap/repair .ai/ before work.
Use `date '+%Y-%m-%d %H:%M %Z'` for real local timestamps.
BEFORE YOU FINISH EVERY RESPONSE, complete the handoff write-back:
- Append to .ai/conversations/LOG.md
- Update .ai/conversations/HANDOFF.md if files changed or decisions made
- Create a session file at .ai/conversations/sessions/YYYY-MM-DD/HHMMSS-agent-task-slug.md if files changed or decisions made
- In your final response, mention that handoff was updated or explain why no handoff write was needed
- Identify yourself by agent name in all writesStep 7: Report to the user
Agent handoff system initialized.
Discovered: {N} reference documents, {N} feature specs, {N} archived docs.
Key documents: {list top 3}
Active work detected: {feature/branch or "none detected"}
Agent configs updated: {list of files where snippet was injected}
Gaps: {any missing elements like "no test directory found"}---
Stale Detection
HANDOFF.md stale (> 7 days since last update): 1. Do NOT blindly trust the handoff state 2. Run git log --oneline --since="7 days ago" to check what changed 3. Cross-reference git history with HANDOFF.md 4. Update HANDOFF.md with current state before proceeding 5. Add a note: [stale] Handoff was {N} days old. Refreshed from git history.
PATHS.md references a file that no longer exists: 1. Remove the stale entry 2. Check if the file was renamed, moved, or superseded 3. Add the replacement if found 4. Log the cleanup in LOG.md
---
Size Limits
| File | Max Lines | Enforcement |
|---|---|---|
| PROJECT.md | ~80 | Stable — only update when stack or architecture changes |
| PATHS.md | ~150 | Collapse less-important entries into directory summaries |
| PLAN.md | ~60 | Track active feature only. Completed → one-liner |
| HANDOFF.md | ~100 | Rolling window: max 15-20 Recent Completions. Oldest → LOG.md |
| LOG.md | ~500 | Archive entries older than 90 days to LOG-archive-YYYY.md |
| Session files | ~80 each | Reference commit hashes instead of repeating diffs |
Startup read cost: ~800-1500 tokens for all 4 files combined. Per-task write cost: ~500-1200 tokens depending on complexity.
---
Concurrent Agent Safety
When two agents work simultaneously, file conflicts can occur.
Prevention:
- HANDOFF.md Active Work lists what each agent is working on.
Before starting, check if another agent is currently active.
- Session files never conflict — each agent writes its own timestamped file.
- LOG.md is append-only — conflicts are simple to resolve (keep both entries).
If a merge conflict occurs in HANDOFF.md: 1. Keep both agents' Active Work entries 2. Merge Recent Completions chronologically 3. Union all Key Context entries
---
Session File Protocol
Agents must create a session file whenever they modify files, make a decision, run an investigation that future agents may need, or take over another agent's active work.
1. Read the four startup files. 2. Get real local time from the environment. 3. Create the date directory: mkdir -p .ai/conversations/sessions/$(date +%F). 4. Use this filename: .ai/conversations/sessions/YYYY-MM-DD/HHMMSS-agent-task-slug.md. 5. Keep the file short and factual. Link to changed files, docs, commits, tests, and blockers rather than pasting large diffs. 6. Reference the session file from HANDOFF.md Active Work or Recent Completions. 7. Append a matching LOG.md entry. 8. In the final response to the user, say that handoff was updated. If no write was needed, say why.
If an agent writes LOG.md/HANDOFF.md but no session file for a file-changing task, the handoff is incomplete and the next agent should repair it by creating a catch-up session file from available evidence.
---
Monorepo Projects
- Place
.ai/at the repository root, not inside individual packages - PATHS.md should list all packages/services with their paths
- PLAN.md can track work across packages — use package prefixes
- Session files should note which package(s) were modified
---
Rules
1. Always read before work. The 4 context files at conversation start. No exceptions. 2. Always write after work. Even for Q&A — a question answered today is context tomorrow. 3. Be concise in LOG.md. 3-5 lines per entry. Full details in session files. 4. Respect size limits. Archive LOG.md when it exceeds ~500 lines. 5. Promote decisions. Architecture/design choices → decisions/ directory. 6. Don't duplicate git history. Reference commit hashes, not diffs. 7. Use real timestamps. Never placeholders. 8. Tag every LOG.md entry. Tags enable scanning. 9. Keep PATHS.md accurate. New file or doc → update PATHS.md. 10. Update PLAN.md on progress. Mark tasks done, add blockers, note the agent. 11. Progressive disclosure. HANDOFF.md → session file → source files. 12. Identify yourself. Include agent name in all writes. 13. LOG.md is append-only. Never delete entries. 14. Verify on resume. Check files exist before continuing another agent's work. 15. Read docs before implementation. Check PATHS.md for relevant specs/plans. 16. Index new documents immediately. Don't leave them for the next agent. 17. Current over archived. Never reference an archived doc as authoritative. 18. Record your sources. List consulted docs in session file References section.
Agent Handoff (always active)
<!-- agent-handoff:v3 -->
You are part of a multi-agent workflow. Multiple AI agents work on this project at different times. Each agent has isolated conversation history. A shared .ai/ directory bridges that gap.
ON EVERY CONVERSATION START — before doing any work, read these files:
1. .ai/PROJECT.md — Tech stack, architecture, conventions 2. .ai/PATHS.md — Key files and reference document index 3. .ai/PLAN.md — Current plan and task status 4. .ai/conversations/HANDOFF.md — What other agents did, what's active, blockers
If any file is missing, empty, or still contains installer placeholders, repair the handoff system before continuing: create the .ai/ directory structure, scan the project, and populate the context files. See the templates in the agent-handoff skill reference files for exact formats.
Before writing timestamps or session filenames, get the real local time from the environment (date '+%Y-%m-%d %H:%M %Z' and date '+%Y-%m-%d/%H%M%S' on Unix-like systems). Do not infer the date from model memory, old docs, or previous handoff entries.
BEFORE YOU FINISH EVERY RESPONSE, complete the handoff write-back. Do not stop after only reading handoff context.
- Always: Append to
.ai/conversations/LOG.md. - Always for file changes, tests, investigations, plans, or decisions: update
.ai/conversations/HANDOFF.md and create a session file in .ai/conversations/sessions/YYYY-MM-DD/.
- If architecture/design decision: Write to
.ai/conversations/decisions/. - If project structure changed: Update
.ai/PATHS.md. - If plan status changed: Update
.ai/PLAN.md. - In your final response: mention that handoff was updated, or explain why no
handoff write was needed.
Session filenames must be unique and sortable: .ai/conversations/sessions/YYYY-MM-DD/HHMMSS-agent-task-slug.md.
Identify yourself by agent name in all writes. For simple Q&A with no file changes, a one-liner in LOG.md is sufficient.
#!/usr/bin/env bash
set -euo pipefail
# Agent Handoff — Universal Installer
# Installs the agent-handoff skill for ALL detected agents in a project.
#
# Usage:
# curl -fsSL https://raw.githubusercontent.com/wecansync/agent-skills/main/skills/agent-handoff/install.sh | bash
# # or
# bash install.sh [--project-dir /path/to/project]
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR=""
INJECT_MARKER="## Agent Handoff (always active)"
INJECT_VERSION_MARKER="<!-- agent-handoff:v3 -->"
# Parse flags
while [[ $# -gt 0 ]]; do
case $1 in
--project-dir) PROJECT_DIR="$2"; shift 2 ;;
--help|-h)
echo "Agent Handoff — Universal Installer"
echo ""
echo "Usage:"
echo " bash install.sh # install in current directory"
echo " bash install.sh --project-dir /path/to # install in specific project"
echo ""
echo "This script MUST be run from your project root (or use --project-dir)."
echo "Do NOT install at user scope (~/.claude/skills/) — the .ai/ context"
echo "files and agent config snippets must live inside the project."
exit 0
;;
*) shift ;;
esac
done
# Resolve project directory
if [[ -z "$PROJECT_DIR" ]]; then
PROJECT_DIR="$(pwd)"
fi
PROJECT_DIR="$(cd "$PROJECT_DIR" && pwd)"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
info() { echo -e "${BLUE}[info]${NC} $1"; }
success() { echo -e "${GREEN}[done]${NC} $1"; }
warn() { echo -e "${YELLOW}[skip]${NC} $1"; }
err() { echo -e "${RED}[error]${NC} $1"; }
step() { echo -e "${GREEN} +${NC} $1"; }
copy_if_different() {
local source="$1"
local target="$2"
if [[ ! -f "$source" ]]; then
return
fi
mkdir -p "$(dirname "$target")"
if [[ -f "$target" ]] && [[ "$(cd "$(dirname "$source")" && pwd)/$(basename "$source")" == "$(cd "$(dirname "$target")" && pwd)/$(basename "$target")" ]]; then
return
fi
if [[ -f "$target" ]] && cmp -s "$source" "$target"; then
return
fi
cp "$source" "$target"
}
echo ""
echo "============================================"
echo " Agent Handoff — Universal Installer"
echo "============================================"
echo ""
# ---------------------------------------------------------------------------
# Pre-flight: Validate project scope
# ---------------------------------------------------------------------------
# Detect if running inside a user home config directory (wrong scope)
case "$PROJECT_DIR" in
"$HOME/.claude"*|"$HOME/.config"*|"$HOME/.local"*|"$HOME/Library"*)
err "Detected user-scope directory: $PROJECT_DIR"
echo ""
echo " Agent Handoff must be installed at PROJECT scope, not user scope."
echo " The .ai/ context files and agent config snippets must live inside"
echo " your project so all agents (Claude, Codex, Cursor, etc.) can access them."
echo ""
echo " Run this script from your project root instead:"
echo ""
echo " cd /path/to/your/project"
echo " bash install.sh"
echo ""
echo " Or specify the project directory:"
echo ""
echo " bash install.sh --project-dir /path/to/your/project"
echo ""
exit 1
;;
esac
# Check for signs this is actually a project root
IS_PROJECT=false
if [[ -d "$PROJECT_DIR/.git" ]]; then
IS_PROJECT=true
elif [[ -f "$PROJECT_DIR/package.json" ]] || [[ -f "$PROJECT_DIR/composer.json" ]] || \
[[ -f "$PROJECT_DIR/go.mod" ]] || [[ -f "$PROJECT_DIR/Cargo.toml" ]] || \
[[ -f "$PROJECT_DIR/pyproject.toml" ]] || [[ -f "$PROJECT_DIR/requirements.txt" ]] || \
[[ -f "$PROJECT_DIR/Gemfile" ]] || [[ -f "$PROJECT_DIR/pom.xml" ]] || \
[[ -f "$PROJECT_DIR/build.gradle" ]] || [[ -f "$PROJECT_DIR/Makefile" ]] || \
[[ -f "$PROJECT_DIR/README.md" ]]; then
IS_PROJECT=true
fi
if [[ "$IS_PROJECT" == false ]]; then
warn "No project markers found (no .git, package.json, composer.json, etc.)"
echo ""
echo -e " ${YELLOW}Are you sure this is your project root?${NC}"
echo " Directory: $PROJECT_DIR"
echo ""
echo " Agent Handoff must be installed at project scope — the .ai/ directory"
echo " and agent config files (CLAUDE.md, codex.md, etc.) must live in the"
echo " project so all agents can read them."
echo ""
read -r -p " Continue anyway? [y/N] " response
case "$response" in
[yY][eE][sS]|[yY]) echo "" ;;
*)
echo ""
echo " Aborted. Run from your project root:"
echo " cd /path/to/your/project && bash install.sh"
exit 1
;;
esac
fi
info "Project directory: $PROJECT_DIR"
echo ""
# ---------------------------------------------------------------------------
# Step 1: Resolve the inject snippet
# ---------------------------------------------------------------------------
INJECT_FILE=""
if [[ -f "$SCRIPT_DIR/inject.md" ]]; then
INJECT_FILE="$SCRIPT_DIR/inject.md"
elif [[ -f "$PROJECT_DIR/.claude/skills/agent-handoff/inject.md" ]]; then
INJECT_FILE="$PROJECT_DIR/.claude/skills/agent-handoff/inject.md"
elif [[ -f "$PROJECT_DIR/.agents/skills/agent-handoff/inject.md" ]]; then
INJECT_FILE="$PROJECT_DIR/.agents/skills/agent-handoff/inject.md"
fi
if [[ -z "$INJECT_FILE" ]]; then
# Download inject.md from GitHub
INJECT_FILE="/tmp/agent-handoff-inject.md"
info "Downloading inject.md..."
curl -fsSL "https://raw.githubusercontent.com/wecansync/agent-skills/main/skills/agent-handoff/inject.md" \
-o "$INJECT_FILE" 2>/dev/null || {
echo -e "${RED}[error]${NC} Could not find or download inject.md"
exit 1
}
fi
INJECT_CONTENT=$(cat "$INJECT_FILE")
# ---------------------------------------------------------------------------
# Step 2: Copy skill files to .claude/skills/ and .agents/skills/
# ---------------------------------------------------------------------------
info "Installing skill files..."
SKILL_SOURCE=""
if [[ -f "$SCRIPT_DIR/SKILL.md" ]]; then
SKILL_SOURCE="$SCRIPT_DIR"
fi
for TARGET_BASE in ".claude/skills/agent-handoff" ".agents/skills/agent-handoff"; do
TARGET_DIR="$PROJECT_DIR/$TARGET_BASE"
mkdir -p "$TARGET_DIR/references"
if [[ -n "$SKILL_SOURCE" ]]; then
copy_if_different "$SKILL_SOURCE/SKILL.md" "$TARGET_DIR/SKILL.md"
copy_if_different "$SKILL_SOURCE/inject.md" "$TARGET_DIR/inject.md"
copy_if_different "$SKILL_SOURCE/install.sh" "$TARGET_DIR/install.sh"
copy_if_different "$SKILL_SOURCE/references/templates.md" "$TARGET_DIR/references/templates.md"
copy_if_different "$SKILL_SOURCE/references/examples.md" "$TARGET_DIR/references/examples.md"
step "Installed skill files in $TARGET_BASE/"
else
# Download from GitHub
for FILE in SKILL.md inject.md; do
curl -fsSL "https://raw.githubusercontent.com/wecansync/agent-skills/main/skills/agent-handoff/$FILE" \
-o "$TARGET_DIR/$FILE" 2>/dev/null || true
done
curl -fsSL "https://raw.githubusercontent.com/wecansync/agent-skills/main/skills/agent-handoff/install.sh" \
-o "$TARGET_DIR/install.sh" 2>/dev/null || true
for FILE in templates.md examples.md; do
curl -fsSL "https://raw.githubusercontent.com/wecansync/agent-skills/main/skills/agent-handoff/references/$FILE" \
-o "$TARGET_DIR/references/$FILE" 2>/dev/null || true
done
step "Downloaded skill files to $TARGET_BASE/"
fi
done
# ---------------------------------------------------------------------------
# Step 3: Inject snippet into agent config files
# ---------------------------------------------------------------------------
inject_into_file() {
local file="$1"
local label="$2"
if [[ -f "$file" ]]; then
if grep -qF "$INJECT_VERSION_MARKER" "$file" 2>/dev/null; then
warn "$label — already injected"
return
fi
if grep -qF "$INJECT_MARKER" "$file" 2>/dev/null; then
echo "" >> "$file"
echo "$INJECT_CONTENT" >> "$file"
step "$label — handoff snippet upgraded"
return
fi
echo "" >> "$file"
echo "$INJECT_CONTENT" >> "$file"
step "$label — snippet injected"
else
echo "$INJECT_CONTENT" > "$file"
step "$label — created with snippet"
fi
}
echo ""
info "Injecting handoff instructions into agent config files..."
INJECTED=0
# Claude Code
if [[ -f "$PROJECT_DIR/CLAUDE.md" ]] || [[ -d "$PROJECT_DIR/.claude" ]]; then
inject_into_file "$PROJECT_DIR/CLAUDE.md" "CLAUDE.md (Claude Code)"
INJECTED=$((INJECTED + 1))
else
inject_into_file "$PROJECT_DIR/CLAUDE.md" "CLAUDE.md (Claude Code)"
INJECTED=$((INJECTED + 1))
fi
# Codex (OpenAI)
inject_into_file "$PROJECT_DIR/codex.md" "codex.md (Codex)"
INJECTED=$((INJECTED + 1))
# AGENTS.md (multi-agent — used by Codex, Antigravity, Specify, and other tools)
inject_into_file "$PROJECT_DIR/AGENTS.md" "AGENTS.md (multi-agent / Antigravity)"
INJECTED=$((INJECTED + 1))
# Cursor
if [[ -f "$PROJECT_DIR/.cursorrules" ]] || [[ -d "$PROJECT_DIR/.cursor" ]]; then
inject_into_file "$PROJECT_DIR/.cursorrules" ".cursorrules (Cursor)"
INJECTED=$((INJECTED + 1))
fi
# Windsurf
if [[ -f "$PROJECT_DIR/.windsurfrules" ]]; then
inject_into_file "$PROJECT_DIR/.windsurfrules" ".windsurfrules (Windsurf)"
INJECTED=$((INJECTED + 1))
fi
# Gemini CLI / older Antigravity
if [[ -f "$PROJECT_DIR/GEMINI.md" ]] || [[ -d "$PROJECT_DIR/.gemini" ]]; then
inject_into_file "$PROJECT_DIR/GEMINI.md" "GEMINI.md (Gemini CLI / older Antigravity)"
INJECTED=$((INJECTED + 1))
fi
# OpenCode
if [[ -d "$PROJECT_DIR/.opencode" ]]; then
mkdir -p "$PROJECT_DIR/.opencode"
inject_into_file "$PROJECT_DIR/.opencode/instructions.md" ".opencode/instructions.md (OpenCode)"
INJECTED=$((INJECTED + 1))
fi
# Copilot
if [[ -f "$PROJECT_DIR/.github/copilot-instructions.md" ]] || [[ -d "$PROJECT_DIR/.github" ]]; then
mkdir -p "$PROJECT_DIR/.github"
inject_into_file "$PROJECT_DIR/.github/copilot-instructions.md" ".github/copilot-instructions.md (Copilot)"
INJECTED=$((INJECTED + 1))
fi
# ---------------------------------------------------------------------------
# Step 4: Create .ai/ directory structure
# ---------------------------------------------------------------------------
echo ""
info "Creating .ai/ directory structure..."
mkdir -p "$PROJECT_DIR/.ai/conversations/decisions" \
"$PROJECT_DIR/.ai/conversations/sessions" \
"$PROJECT_DIR/.ai/conversations/sessions/$(date +%F)"
for FILE in PROJECT.md PATHS.md PLAN.md; do
if [[ ! -f "$PROJECT_DIR/.ai/$FILE" ]]; then
step ".ai/$FILE — created (placeholder, bootstrap required on first agent run)"
touch "$PROJECT_DIR/.ai/$FILE"
else
warn ".ai/$FILE — already exists"
fi
done
if [[ ! -f "$PROJECT_DIR/.ai/conversations/HANDOFF.md" ]]; then
cat > "$PROJECT_DIR/.ai/conversations/HANDOFF.md" <<'HANDOFF_EOF'
# Agent Handoff
Last updated: —
## Active Work
No prior agent activity recorded.
## Recent Completions
(empty)
## Pending Decisions
None
## Key Context
- Agent handoff system initialized — awaiting first agent session
HANDOFF_EOF
step ".ai/conversations/HANDOFF.md — created"
else
warn ".ai/conversations/HANDOFF.md — already exists"
fi
if [[ ! -f "$PROJECT_DIR/.ai/conversations/LOG.md" ]]; then
{
echo "# Agent Activity Log"
echo ""
echo "<!-- agent-handoff: append-only; use real local time from the environment -->"
} > "$PROJECT_DIR/.ai/conversations/LOG.md"
step ".ai/conversations/LOG.md — created"
else
warn ".ai/conversations/LOG.md — already exists"
fi
# ---------------------------------------------------------------------------
# Step 5: Add .ai/ to .gitignore guidance
# ---------------------------------------------------------------------------
echo ""
if [[ -f "$PROJECT_DIR/.gitignore" ]]; then
if grep -qF ".ai/conversations/sessions/" "$PROJECT_DIR/.gitignore" 2>/dev/null; then
warn ".gitignore — already configured"
else
info "Consider adding to .gitignore (session files can be noisy):"
echo " .ai/conversations/sessions/"
echo " .ai/conversations/LOG-archive-*.md"
fi
fi
# ---------------------------------------------------------------------------
# Summary
# ---------------------------------------------------------------------------
echo ""
echo "============================================"
echo -e " ${GREEN}Installation complete${NC}"
echo "============================================"
echo ""
echo " Skill files: .claude/skills/agent-handoff/"
echo " .agents/skills/agent-handoff/"
echo " Context dir: .ai/"
echo " Injected into: $INJECTED agent config file(s)"
echo ""
echo " Next steps:"
echo ""
echo " 1. Open Claude Code in this project"
echo ""
echo " 2. Run:"
echo ""
echo " /agent-handoff"
echo ""
echo " Or ask any agent:"
echo " Scan this project and populate the .ai context files."
echo ""
echo " 3. Done — every agent will now read .ai/ on start and"
echo " write updates after each task automatically."
echo ""
echo " To add more agents later, re-run this script."
echo ""
Agent Handoff — Examples
Real-world examples showing how the .ai/ files look in practice across different project types and complexity levels.
---
Example 1: PROJECT.md — PHP/Laravel project (documentation-rich)
# Project: Order Management Middleware
## Overview
Multi-brand order management middleware between e-commerce storefronts and an ERP
system. Handles order ingestion, fulfillment orchestration (internal drivers, courier
services, pickup), delivery tracking with PIN verification, financial settlements,
and a Livewire admin panel for multi-location retail operations.
## Tech Stack
- **Language:** PHP 8.3 with `declare(strict_types=1)` on all files
- **Framework:** Laravel 12
- **Database:** MySQL 8.x
- **Frontend:** Livewire 3 + Alpine.js 3 + Tailwind CSS 3
- **Auth:** Laravel Sanctum v4
- **RBAC:** Spatie Laravel Permission v6
- **State machines:** asantibanez/laravel-eloquent-state-machines v6
- **Testing:** PHPUnit 11
## Architecture
Laravel 12 monolith serving: REST API (/api/v1/*), Livewire admin panel (/dashboard/*),
outbound ERP client, and catalog proxy service.
## Key Documents
| Document | Path | Purpose |
|----------|------|---------|
| TRD v5.0 | `docs/TRD-v5.0-final.md` | Source of truth for all features and requirements |
| Implementation Plan | `docs/implementation-plan-v5.md` | Global phasing and priority of all features |
| Project Overview | `docs/project-overview-v5.md` | High-level goals, stakeholders, domain context |
| API Integration Guide | `docs/api-docs/integration-guide.md` | External API reference |
| Delivery Cases Guide | `docs/delivery-cases-guide.md` | Fulfillment flow walkthroughs |
## Conventions
- Service classes in `app/Services/` — no fat controllers
- PHP 8.1 backed enums in `app/Enums/` for all ENUM columns
- All DB changes via migrations — no raw ALTER statements
## How to Run
- Dev server: `php artisan serve`
- Tests: `php artisan test --compact`
- Build frontend: `npm run build`
- Fresh DB: `php artisan migrate:fresh --seed`
## How to Deploy
VPS deployment to Ubuntu via deployer. Post-deploy:
`php artisan migrate --force && php artisan config:cache && php artisan route:cache`---
Example 2: PROJECT.md — TypeScript/Next.js project (minimal docs)
# Project: Analytics Dashboard
## Overview
Real-time analytics dashboard for SaaS metrics. Ingests events via webhooks,
stores in ClickHouse, renders interactive charts and cohort analysis for
product teams.
## Tech Stack
- **Language:** TypeScript 5.6
- **Framework:** Next.js 15 (App Router)
- **Database:** ClickHouse (analytics), PostgreSQL 16 (app data)
- **ORM:** Drizzle ORM
- **Frontend:** React 19 + Tailwind CSS 4 + Recharts
- **Auth:** NextAuth.js v5
- **Testing:** Vitest + Playwright
## Architecture
Next.js 15 monolith with App Router. Server Components for data-heavy pages,
Client Components for interactive charts. API routes handle webhook ingestion.
ClickHouse for time-series queries, PostgreSQL for user/team/config data.
## Key Documents
| Document | Path | Purpose |
|----------|------|---------|
| README | `README.md` | Architecture overview and setup |
| API Spec | `openapi.yaml` | Webhook and query API contract |
| ADR Index | `docs/adrs/` | Architecture Decision Records |
## Conventions
- Collocate components: `app/dashboard/page.tsx` + `app/dashboard/components/`
- Server Components by default, `"use client"` only when needed
- Drizzle schema in `src/db/schema/`, one file per table
## How to Run
- Dev: `pnpm dev`
- Tests: `pnpm test` (unit) / `pnpm test:e2e` (Playwright)
- Build: `pnpm build`
## How to Deploy
Vercel auto-deploy from `main`. Preview deploys on PRs.---
Example 3: PATHS.md — documentation-rich project
# Key Paths
## Application Code
- `app/Models/` — Eloquent models (Order, Delivery, Settlement, Transfer, etc.)
- `app/Services/` — Business logic (FulfillmentService, SettlementService, etc.)
- `app/Enums/` — Backed enums (OrderStatus, DeliveryStatus, PaymentMethod, etc.)
- `app/Http/Controllers/Api/` — REST API endpoints
- `app/Http/Controllers/Dashboard/` — Admin panel controllers
## Database
- `database/migrations/` — Schema changes
- `database/seeders/` — Role, permission, and demo data seeders
## Configuration
- `.env.example` — Environment template
- `config/` — Framework config files
## Tests
- `tests/Feature/` — Feature tests (PHPUnit)
- `tests/Unit/` — Unit tests (PHPUnit)
## Reference Documents (current)
### Requirements
- `docs/TRD-v5.0-final.md` — Technical Requirements Document, source of truth
- `docs/TRD-v5.0-implementation-analysis.md` — Gap analysis: TRD vs codebase
### Implementation Plans
- `docs/implementation-plan-v5.md` — Global plan with feature phasing
- `docs/project-progress-v5.md` — Progress tracking
- `docs/plans/019-per-store-deliveries.md` — Upcoming feature plan
- `docs/plans/020-api-data-population.md` — Upcoming feature plan
### Guides
- `docs/delivery-cases-guide.md` — Fulfillment flow walkthroughs
- `docs/roles-guide.md` — RBAC role definitions and permissions
- `docs/admin-guide.md` — Admin panel user guide
- `docs/demo-guide-v2.0.md` — Demo environment setup
### API Documentation
- `docs/api-docs/integration-guide.md` — External API integration
- `docs/api-docs/api.postman_collection.json` — Postman collection
### Agent & Project Config
- `CLAUDE.md` — Agent coding conventions
- `README.md` — Project readme
## Feature Specs
17 feature specs in `specs/`, numbered 001 through 018.
### Structure per feature
Each `specs/{NNN-feature-name}/` contains:
- `spec.md` — Requirements and acceptance criteria
- `plan.md` — Implementation plan with task breakdown
- `tasks.md` — Actionable task checklist
- `research.md` — Research notes from analysis
- `data-model.md` — Database schema changes
- `contracts/` — API contracts and interface definitions
- `checklists/requirements.md` — Verification checklist
### Active / Recent
- `specs/018-suborder-physical-split/` — Current: multi-location order splitting
- `specs/017-trd-v5-alignment/` — Recent: TRD v5 reconciliation
- `specs/016-inter-branch-transfers/` — Recent: transfer system with QR verification
## Archived Documents
Older versions — reference only, NOT authoritative.
- `docs/archive/TRD-v4.md` — (superseded by TRD-v5.0-final.md)
- `docs/archive/implementation-plan-v4.md` — (superseded by v5)
- `docs/archive/` — 15+ historical docs
## Agent Handoff
- `.ai/conversations/HANDOFF.md` — Agent activity and current state
- `.ai/conversations/LOG.md` — Full activity history---
Example 4: PATHS.md — minimal project (no docs/ directory)
# Key Paths
## Application Code
- `src/app/` — Next.js App Router pages and layouts
- `src/components/` — React components
- `src/hooks/` — Custom React hooks
- `src/db/` — Drizzle schema and queries
- `src/lib/` — Shared utilities
## Configuration
- `.env.example` — Environment template
- `next.config.ts` — Next.js configuration
- `drizzle.config.ts` — Database configuration
## Tests
- `__tests__/` — Vitest unit tests
- `e2e/` — Playwright E2E specs
## Reference Documents (current)
- `README.md` — Architecture overview and setup instructions
- `openapi.yaml` — Webhook and query API contract (OpenAPI 3.1)
- `CONTRIBUTING.md` — Code style and PR guidelines
- `docs/adrs/001-clickhouse-for-analytics.md` — Why ClickHouse over TimescaleDB
- `docs/adrs/002-app-router-migration.md` — Pages → App Router migration notes
## Feature Specs
No dedicated specs directory. Work tracked in GitHub Issues with `feature/` labels.
## Agent Handoff
- `.ai/conversations/HANDOFF.md` — Agent activity and current state
- `.ai/conversations/LOG.md` — Full activity history---
Example 5: HANDOFF.md — multiple agents collaborating
# Agent Handoff
Last updated: 2026-05-20 15:45 by opencode
## Active Work
- Implementing 018-suborder-physical-split — Phase 2: Models & Relations
- Last session: [sessions/2026-05-20-153022-opencode.md]
- Status: Migrations done, Order model updated, Settlement model next
- Blocker: None
## Recent Completions
- [2026-05-20 opencode] Updated Order model with parent/child relations #feature
- [2026-05-20 opencode] Created 3 migration files for suborder split #migration
- [2026-05-20 claude] Created spec and plan for 018-suborder-physical-split #spec
- [2026-05-20 claude] Answered question about settlement flow architecture #question
- [2026-05-19 claude] Fixed COD calculation to include delivery fees (PR #21) #bugfix
- [2026-05-19 codex] Added unit tests for delivery fee calculation #test
## Pending Decisions
- Whether to cascade-delete suborders when parent is cancelled
→ context in decisions/2026-05-20-suborder-cascade-delete.md
## Key Context
- ERP sync is feature-flagged via `erp_settlement_sync` setting
- PIN verification toggleable via `pin_enabled` setting
- Requirements doc is source of truth — check before implementing---
Example 6: Session file with document references
---
agent: opencode
started: 2026-05-20 15:30
task: Implement Order model changes for suborder physical split
tags: [#feature, #model]
---
## Summary
Updated the Order model for parent-child suborder relationships per the 018 spec.
Added two relationships, a scope, and updated casts.
## Files Created/Modified
- `app/Models/Order.php` — added parentOrder(), subOrders(), scopeParentOnly(), casts
- `app/Models/Settlement.php` — added suborder_id to fillable
## Decisions Made
- Used nullable FK (parent_order_id) over polymorphic — simpler queries
(see decisions/2026-05-20-suborder-relations.md)
## Issues/Blockers Found
- None
## What's Next
- Update state machine for split transitions
- Add splitOrder() to FulfillmentService
- Update admin panel order list to use parentOnly() scope
## References
- `specs/018-suborder-physical-split/spec.md` — feature requirements
- `specs/018-suborder-physical-split/data-model.md` — schema design
- `docs/TRD-v5.0-final.md` (Section 4.3) — suborder requirements
- PR #21 — related fix, touched same Settlement model---
Example 7: LOG.md — mixed entry types
# Agent Activity Log
---
## 2026-05-20 15:30 — opencode #feature
**Task:** Implement Order model changes for suborder physical split
**Outcome:** Added parent_order_id, is_suborder fields. Created parent/children relations.
**Files:** app/Models/Order.php, app/Models/Settlement.php
**Next:** Update state machine for split transitions
---
---
## 2026-05-20 14:30 — opencode #migration
**Task:** Create migrations for 018-suborder-physical-split
**Outcome:** 3 migration files: alter orders, alter settlements, backfill
**Files:** database/migrations/2026_05_20_001*.php, 002*.php, 003*.php
**Next:** Update Eloquent models
---
---
## 2026-05-20 10:15 — claude #question
How does the settlement flow work? → Settlements created per-order on delivery
completion. COD includes delivery_fee. ERP sync gated by setting.
---
---
## 2026-05-19 16:00 — claude #bugfix
**Task:** Fix COD calculation not including delivery fees
**Outcome:** Updated SettlementService. Fixed 3 Livewire views.
**Files:** app/Services/SettlementService.php, resources/views/livewire/orders/*.blade.php
**Next:** PR #21 created — needs review
------
Example 8: Decision file
# Decision: Nullable FK for suborder parent reference
Date: 2026-05-20
Agent: opencode
Status: accepted
## Context
Feature requires orders to have parent-child relationships for multi-location
fulfillment splitting.
## Decision
Use a nullable `parent_order_id` foreign key on the orders table pointing back
to `orders.id`. Parent orders have NULL parent_order_id.
## Rationale
Only one model type involved (Order → Order). Polymorphic adds complexity for
no benefit. Nullable FK is a standard pattern with built-in ORM relationship support.
## Alternatives Considered
- Polymorphic relation — unnecessary when both sides are the same model
- Separate suborders table — 95% field overlap, maintenance burden
- JSON column — can't query, can't enforce FK constraints
## Consequences
- All list queries must filter to exclude suborders
- Settlement logic needs to handle both parent and suborder rows
- Cascade delete is NOT automatic — needs explicit handling---
Example 9: First-run bootstrap report
Agent handoff system initialized.
Discovered: 12 reference documents, 17 feature specs, 15 archived docs.
Key documents:
- docs/TRD-v5.0-final.md (requirements, source of truth)
- docs/implementation-plan-v5.md (global phasing)
- docs/project-overview-v5.md (stakeholder context)
Active work detected: 018-suborder-physical-split (highest spec + recent commits)
Gaps: none
Files created:
.ai/PROJECT.md, .ai/PATHS.md, .ai/PLAN.md,
.ai/conversations/HANDOFF.md, .ai/conversations/LOG.md---
Quick Reference: When to Create/Update What
| Scenario | LOG.md | HANDOFF.md | Session | Decision | PLAN.md | PATHS.md |
|---|---|---|---|---|---|---|
| Simple Q&A | one-liner | skip | skip | skip | skip | skip |
| Q&A that reveals insight | one-liner | if important | skip | if decision | skip | skip |
| Bug fix | full entry | update | create | skip usually | update status | skip |
| New feature work | full entry | update | create | if choices made | update status | if new files |
| Spec/plan creation | full entry | update | create | if arch decisions | update | skip |
| Code review | full entry | update | create if findings | skip | skip | skip |
| Migration/schema change | full entry | update | create | if design choice | update status | skip |
| New doc created | full entry | update | skip usually | skip | skip | add to index |
| Doc version bumped | one-liner | skip | skip | skip | skip | update version |
| First-run bootstrap | skip | create | skip | skip | create | create full |
Agent Handoff — File Templates
Reference templates for all .ai/ files. Used during bootstrapping and as a format guide for ongoing writes.
---
PROJECT.md
Stable project-level context. Updated rarely.
# Project: {name}
## Overview
{One paragraph: what the project does, who it serves, domain context}
## Tech Stack
- **Language:** {e.g., PHP 8.3, Python 3.12, TypeScript 5.x}
- **Framework:** {e.g., Laravel 12, Next.js 15, Django 5.1}
- **Database:** {e.g., MySQL 8.x, PostgreSQL 16, MongoDB 7}
- **Frontend:** {e.g., Livewire 3, React 19, Vue 3}
- **Key packages:** {list with purpose — only include packages that affect architecture}
## Architecture
{2-3 sentences: monolith vs microservice, API structure, deployment model}
## Key Documents
These are the most important reference documents. Read before making architectural
decisions or starting new features.
| Document | Path | Purpose |
|----------|------|---------|
| {name} | `{path}` | {one-line purpose} |
If the project has no formal documentation beyond README, this section can list
just the README and any inline architecture notes.
## Conventions
- {Convention 1}
- {Convention 2}
## How to Run
- Dev server: {command}
- Tests: {command}
- Build: {command}
## How to Deploy
{Brief deployment process, or "See CI/CD pipeline" if automated}---
PATHS.md
Filesystem map and reference document index. Primary lookup for "where is X?" Updated when project structure changes or new important documents are created.
# Key Paths
## Application Code
- `{src dir}/` — {description}
- `{models dir}/` — {description}
{...framework-specific directories}
## Configuration
- `.env.example` — Environment template
- `{config dir}/` — Configuration files
{...}
## Tests
- `{test dir}/` — {test framework} tests
## Reference Documents (current)
High-value documents that agents should know about. Organized by category.
### {Category 1, e.g., Requirements / Design / Architecture}
- `{path}` — {one-line description}
### {Category 2, e.g., Guides / Operations}
- `{path}` — {one-line description}
### {Category 3, e.g., API Documentation}
- `{path}` — {one-line description}
### Agent & Project Config
- `{CLAUDE.md, .cursorrules, codex.md, etc.}` — {purpose}
- `README.md` — Project readme
## Feature Specs / Plans
{Describe the project's planning system — could be specs/, rfcs/, adrs/, GitHub
Issues, Linear tickets, or "no formal system detected."}
{If a directory-based system exists, document the pattern:}
### Structure per feature
Each `{pattern}/` contains:
- `{file1}` — {purpose}
- `{file2}` — {purpose}
{...detected pattern}
### Active / Recent
- `{path}` — {status}: {description}
## Archived Documents
{Older versions — reference only, NOT authoritative.}
- `{path}` — (superseded by {current version})
## Agent Handoff
- `.ai/` — Cross-agent conversation bridge (this system)
- `.ai/conversations/HANDOFF.md` — Agent activity and current state
- `.ai/conversations/LOG.md` — Full activity history---
PLAN.md
Current implementation plan. Updated after each task that progresses the plan.
# Current Plan
## Active Work
**{Feature/task name}** — {one-line description}
- Spec/Issue: `{path or URL}`
- Plan: `{path, if exists}`
## Task Status
| Task | Status | Agent | Date |
|------|--------|-------|------|
| {task 1} | done | {agent} | {date} |
| {task 2} | in-progress | {agent} | {date} |
| {task 3} | pending | — | — |
## Blockers
- {blocker, or "None"}
## Key Decisions
- {decision} → see `decisions/{file}`For projects without a formal spec system, PLAN.md can track work from any source: GitHub Issues, Jira tickets, user instructions, or even "the user asked me to..."
---
HANDOFF.md
Rolling window of agent activity. Max 15-20 entries in Recent Completions.
# Agent Handoff
Last updated: {YYYY-MM-DD HH:MM} by {agent-name}
## Active Work
- {What's being worked on}
- Last session: [sessions/{filename}]
- Status: {where it stands}
- Blocker: {if any, or "None"}
## Recent Completions
- [{YYYY-MM-DD} {agent}] {what was done} #{tag}
{... max 15-20 entries, then oldest roll off to LOG.md}
## Pending Decisions
- {Decision needed} → context in {file reference}
## Key Context
- {Important runtime context: feature flags, env quirks, gotchas}On the very first write (no prior agent activity), set Active Work to whatever the current task is and leave Recent Completions empty.
---
LOG.md (append-only)
Permanent chronological record. Each entry is 3-5 lines.
Tags: #question #bugfix #feature #refactor #spec #plan #review #decision #migration #config #test #docs #deploy #setup
Full entry format:
---
## {YYYY-MM-DD HH:MM} — {agent-name} #{tag}
**Task:** {what was requested}
**Outcome:** {what was done}
**Files:** {files changed, or "None"}
**Next:** {what should happen next, or "N/A"}
---Compact format for simple Q&A:
---
## {YYYY-MM-DD HH:MM} — {agent-name} #question
{question} → {brief answer}
---Archival: When LOG.md exceeds ~500 lines, move entries older than 90 days to LOG-archive-YYYY.md in the same directory. Keep the last 90 days in LOG.md.
---
Session file: sessions/YYYY-MM-DD/HHMMSS-agent-task-slug.md
Detailed log for one session. Only read on-demand (resume or investigation). Create the date directory first. Use real local system time, not model memory or dates copied from previous handoff entries.
---
agent: {agent-name}
started: {YYYY-MM-DD HH:MM TZ}
task: {one-line task description}
tags: [#{tag1}, #{tag2}]
---
## Summary
{2-3 sentences: what was done and why}
## Files Created/Modified
- `{path}` — {what changed}
## Decisions Made
- {decision + rationale}
## Issues/Blockers Found
- {issue, or "None"}
## What's Next
- {next steps for whoever picks this up}
## References
- {docs, specs, PRs, or URLs consulted during this session}---
Decision file: decisions/YYYY-MM-DD-topic-slug.md
One file per significant architectural or design decision.
# Decision: {Title}
Date: {YYYY-MM-DD}
Agent: {agent-name}
Status: {accepted | superseded | revisit}
## Context
{Why this decision was needed}
## Decision
{What was decided}
## Rationale
{Why this option, not others}
## Alternatives Considered
- {option} — {why rejected}
## Consequences
- {impact on codebase or future work}Related skills
How it compares
Use as procedural glue instead of hoping each agent re-reads git history or random notes in the repo root.
FAQ
Who is agent-handoff for?
Developers running multiple AI coding agents on one repo who need a standard `.ai/` bridge so sessions do not lose plan status or blockers.
When should I use agent-handoff?
On every agent conversation in Idea research through Operate iteration—whenever you start work (read handoff) and before you stop (write LOG/HANDOFF); especially across Build, Ship, and Operate when another agent may resume tomorrow.
Is agent-handoff safe to install?
It writes under `.ai/` and may scan the project; review the Security Audits panel on this page and keep secrets out of HANDOFF and session files.