Skip to content

harn scratch

harn scratch <subcommand> [options]

A per-agent markdown journal. Each agent has one scratchpad at .harnery/scratch/<instance_id>.md, and every entry is an append-only, timestamped line under a category. It serves two purposes: self-notes that survive in-session compaction (the file is on disk, not in the conversation context, so a note written before a compaction is still readable after), and pull-based peer coordination — another agent can read your scratchpad on demand to pick up where you left off.

The lifecycle is automated by session hooks: the scratchpad is archived at session end, the most-recent archive is surfaced as a recovery cue at the next session start, and archives older than the retention window are pruned. The subcommands below are the same ones those hooks call, plus the everyday add / read you’ll use by hand.

Every entry carries one category, which describes what kind of breadcrumb it is:

note · plan · decision · blocker · question · done · handoff

harn scratch add <category> <text...> # append a timestamped entry to my scratchpad
harn scratch read # render my scratchpad (newest entries first)
harn scratch read --name <peer> # render a peer's scratchpad instead
harn scratch list # summarize every active scratchpad + archive count
harn scratch tail # follow my scratchpad (or a peer's) for new entries
harn scratch lint # validate scratchpad format + size
harn scratch clear --yes # delete my scratchpad (rare; mainly for testing)
harn scratch archive # archive my scratchpad now (idempotent)
harn scratch recovery-cue # emit a one-line "previous session was doing X" hint
harn scratch janitor # prune old archives + sweep orphaned scratchpads

Options are per-subcommand:

Subcommand Flag Description
read --name <name> Read the named peer’s scratchpad (case-insensitive).
read --owner <id> Read by instance_id directly.
read --archive <basename> Read an archived file (e.g. <owner>-<ts>.md).
read --limit <n> Cap entries rendered, newest first (default 50).
list --archives List archive files instead of active scratchpads.
tail --name <name> Tail the named peer’s scratchpad.
tail --owner <id> Tail by instance_id directly.
lint --all Lint every scratchpad in .harnery/scratch/.
lint --owner <id> Lint a specific owner’s scratchpad.
clear --yes Confirm deletion (required).
archive --owner <id> Archive a specific owner’s scratchpad.
recovery-cue --max-age-hours <n> Only surface archives newer than this (default 24).
janitor --days <n> Archive retention in days (default 7).
janitor --quiet Suppress stdout output.
Terminal window
# Leave a breadcrumb for future-self (surviving a compaction)
harn scratch add plan "refactor the retry loop, then wire up the metrics"
# Record a blocker so a peer can see why you stalled
harn scratch add blocker "waiting on the config change agent-Foo is holding"
# Read your own journal, most recent first
harn scratch read
# Read a peer's journal before picking up their thread
harn scratch read --name Foo
# See who has active scratchpads and how big they are
harn scratch list
# Read a specific archived session
harn scratch read --archive 5cc4edab-2026-07-14T10-00-00.md
  • 50 KB hard cap. When a scratchpad exceeds the cap, the oldest entries are auto-pruned so appends never fail. Keep entries terse.
  • Stale-owner banner. Reading a peer’s scratchpad whose heartbeat is older than the freshness window prepends a [STALE: heartbeat Nm old, agent may be dead] banner, so you don’t act on notes from an agent that has since exited.
  • Archives live in .harnery/scratch/archived/. archive moves the live file there; recovery-cue reads the newest one to build the session-start hint; janitor prunes archives past the retention window and sweeps scratchpads whose owning agent is gone.
  • Pull-based, not push. Nothing notifies a peer that you wrote something — they read on demand. To hand someone an actionable note they’ll see, use harn agents ping, which appends a handoff entry to their scratchpad.