/wheypoint
When to invoke: Mark a checkpoint in the current conversation — compact it into a durable handoff document so a fresh agent can resume the work without context loss. Use when the user wants to preserve session state for a later or parallel session — phrases like “hand this off”, “write a handoff”, “drop a wheypoint”, “checkpoint this”, “compact the conversation”, “I’m running low on context”, “save where we are for the next session”, “prep a handoff for another agent”, “/wheypoint”. Use even when the user just says “wrap up” or “I need to clear context” mid-task. Do NOT use for per-phase pipeline handoffs — those belong to /cook, /press, /age, and /cure.
/wheypoint captures just enough state for a cold reader to resume.
/wheypoint is for culture’s end-of-session checkpoint and for the messy mid-task moment when no phase slug applies and context is about to be lost.
Inputs
Section titled “Inputs”- The conversation so far (the primary input).
- Optional argument: a description of what the next session will focus on. When present, treat it as the lens and tailor the document to it. Drop state that does not serve that focus to a one-line pointer.
- Derive a slug from the task (e.g.
auth-retry-backoff). Reuse an existing slug if this session already owns one under.cheese/. - Inventory what already exists. List the
.cheese/artifacts, specs, PRs, issues, commits, and diffs this session produced or touched. These get referenced, never re-summarised. - Rehydrate.
python3 skills/wheypoint/scripts/wheypoint.pyz show --work-id <id>(bundle fallback:${CLAUDE_SKILL_DIR}/scripts/wheypoint.pyz) returns the record. Mandatory after a compaction: a compaction-marked delta is rejected unless the revision it declares as rehydrated is the current one. - Build a semantic
WheypointDelta, not a rewritten document.expected_revision_idis the revision you rehydrated, or the genesis sentinel when this work has no record yet — that sentinel creates the first record, so there is no create step. Omitting a protected decision, question, blocker, or artifact link carries it forward; retiring one takes an explicit transition naming its entry ID, action, and rationale. A focus argument is the delta’s lens. - Commit through the runtime. Pipe the delta as JSON to
wheypoint.pyz commit. It assigns the revision, derivesstatus:, and writes the immutable revision plus the MarkdownWheypointProjectionat.cheese/notes/<slug>.md— a generated projection, never the authority: never hand-edit it, never resume from it. A rejected commit is a real failure: fix the delta and re-commit, never hand-write the note. - Redact secrets on the way out (
## Redaction). - Report durability. State the durability the commit result reports (
canonical-local,repo-snapshot, orpublished); never run a Git commit, push, or publish to raise it. Point at resumption per## Handoff.
Handoff slug
Section titled “Handoff slug”Prepend the standard resumable slug to the top of the file so /cheese --continue can route from it without reading the whole document:
status: ok | gated: <one-line decision> | halt: <one-line reason>next: mold | cook | press | age | cure | affinage | briesearch | culture | hold | tasks | donemode: single | parallelartifact: <path-to-richer-report, or PR ref (PR#<n> / URL) when next: affinage, else none>session: <harness>:<session-id> # optional; auto-filled provenancegit: <branch>@<short-sha> # optional; auto-filled provenancecreated: <UTC ISO-8601> # optional; auto-filled provenanceparents: [<slug>, ...] # optional; lineage (join => 2+, split-child => 1)baseline: none | <block — carries a recorded baseline block forward from an upstream cook/press/cure handoff; see ../cook/references/quality-gates.md><one-line orientation: where the session is and what is mid-flight>mode: is optional for backwards compatibility; omitted mode means mode: single. In mode: single, next: names the skill the cold reader should run, which is the machine-readable form of the suggested-skills section below. Use done only when the work is genuinely finished and the handoff is a record, not a baton. /cheese --continue <slug> resolves the slug through wheypoint.pyz resolve and dispatches next: only from the validated current revision; an absolute note path resolves as an explicit path first. When next: affinage, record the PR reference (PR#<n> or its URL) in artifact: so the resume dispatches /affinage <pr> explicitly rather than relying on branch auto-detection.
When the checkpointed session carries a recorded baseline: block, carry it into the delta unchanged: it is settled state, not something the resumed phase should re-ask about or re-halt on. See ../cook/references/quality-gates.md.
Provenance fields
Section titled “Provenance fields”Four optional provenance fields sit between artifact: and the orientation line. Auto-fill each one from the live session; never take a user-supplied value. All four are optional and additive: a note carrying none of them is valid, and every consumer treats a pre-provenance note (none of these keys) as valid. Placement rule: the orientation line stays the first non-key line, so it must follow whichever of these fields are present.
session: <harness>:<session-id>— the current session’s harness and id, read from the per-harness source map:- claude — the newest
*.jsonlin the encoded-cwd projects dir (~/.claude/projects/<encoded-cwd>/); its basename (minus.jsonl) is the session id. - codex — the
payload.cwdfield in the rollout meta line of the active rollout log. - opencode — the matching row in the
sessiontable. - When the harness is unknown or no log is accessible, omit the field.
<speculative>the newest-mtime claude heuristic can bind the wrong*.jsonlwhen several live sessions share one cwd; the field is optional so a wrong bind is hand-correctable.
- claude — the newest
git: <branch>@<short-sha>— the branch and short commit at capture time. Use any callable, read-only git inspection capability the active harness exposes. CLI transports may rungit status --short --branchfor the branch andgit rev-parse --short HEADfor the short SHA. Omit the field when git inspection is unavailable, outside a git repository, or either value cannot be determined.created: <UTC ISO-8601>— the capture timestamp in UTC ISO-8601 (e.g.2026-07-09T14:32:00Z).parents: [<slug>, ...]— lineage. Empty or absent for a fresh single-thread note. The legacy note-level verbs--join <slugA> <slugB>(one merged note,parents: [<slugA>, <slugB>]) and--split(two child notes, eachparents: [<current-slug>]) sit outside this continuity contract: they rewrite.cheese/notes/Markdown and commit no delta.
status: values
Section titled “status: values”Status is derived by the runtime, never asserted by the author: an active human-blocking question or blocker derives gated: and requires a decision dossier, and no caller can force ok.
ok— the next step is unblocked;/cheese --continueauto-dispatchesnext:.gated: <one-line decision>— work is fine, but the next step is blocked on a human decision. Name the decision in one line. On/cheese --continue, the reader surfaces the decision plus the body’s open-questions/blockers and asks which direction (research / decide / build); it dispatches nothing until the user picks. Never collapse a gate into a bare actionablenext:withstatus: ok— that is the misfire this contract exists to stop. Any open blocker in the body mandatesstatus: gated:, notstatus: ok.halt: <one-line reason>— legacy vocabulary, valid only in hand-written notes read through the legacy fallback, with unchanged semantics: surface the reason, then dispatch the runnablenext:. The runtime never derives it and the derived set stays two-valued on purpose:haltrecords how the previous session ended, while derived status records whether continuation is blocked on a human, and a session can halt on an environment failure with nothing left to decide. That difference is deliberate, not a contradiction to close by addinghaltto the derived set.
next: values and semantics
Section titled “next: values and semantics”Single-value next: is one of the pipeline phases (mold | cook | press | age | cure | affinage), a read-only kickoff (briesearch | culture), hold, tasks (with mode: parallel), or done.
mold/cook/press/age/cure— the pipeline phases. Which one fits the session state (and the mid-phase resume case, e.g./cookinterrupted) is defined by the## Suggested skillsmapping table below, which owns these semantics.affinage— PR has review comments or failing CI. Record the PR reference inartifact:(PR#<n>or URL) so the resume dispatches/affinage <pr>explicitly.briesearch | culture— read-only, low-risk next moves. Understatus: ok,/cheese --continueauto-dispatches them directly (frictionless research/think kickoff), deriving any dispatch argument (e.g.briesearch’s question) from the orientation line. A move that needs a human decision belongs instatus: gated:.hold— restore orientation and wait for instruction; dispatch nothing. For compacting or stringing context along when no action is implied. Distinct fromdone(work finished, record only).done— work genuinely finished; handoff is a record, not a baton. Use only for true terminal completion.- A missing
next:is a malformed handoff./cheese --continueflags it (malformed handoff: next: required) rather than guessing or defaulting. Declare intent explicitly —holdis the value for “no action.”
next: list form
Section titled “next: list form”To kick off several read-only follow-ups from one handoff, next: may be a list with a required order::
next: [briesearch "slug1", briesearch "slug2", culture "slug3"]order: parallel | sequential- Each item is
<skill> "<arg>".order:is required whennext:is a list. order: parallel—/cheese --continuefans out concurrent read agents, one per item, in the same turn.order: sequential— items run in listed order.- The inline list is restricted to read-only skills (
briesearch | culture). Parallel write efforts still require the heavyweightmode: parallel+tasks:block with worktree/branch isolation below; sequential pipeline chaining stays the job of--auto//cook’s fan pathway.
For multiple independent next moves, use mode: parallel, set next: tasks, add a parallel: block, and add a tasks: list immediately after the orientation line. Each task must carry its exact command:; commands may name different skills. Parallel write tasks must never share a checkout. Choose one portable isolation strategy:
worktree_strategy |
Use when | Required fields |
|---|---|---|
existing |
The user already has durable bench checkouts | each write task has distinct worktree:, branch:, and branch_from |
create |
No checkouts exist yet | worktree_root, plus each write task has branch: and branch_from |
harness |
The host can create isolated threads/worktrees | each write task has branch: and branch_from; the host owns checkout creation |
Example:
status: oknext: tasksmode: parallelartifact: noneKIP-76 and KIP-77 are ready to run as independent PR efforts.parallel: isolation: git-worktree worktree_strategy: existingtasks: - slug: kip-77-ai-test-server intent: cook repo: /Users/marcus/Documents/multiplier worktree: /Users/marcus/Documents/multiplier-01 branch: marcus/kip-77-ai-test-server branch_from: origin/main command: /cook .cheese/specs/kip-77-ai-test-server.md - slug: kip-76-ai-service-spin-up intent: cook repo: /Users/marcus/Documents/multiplier worktree: /Users/marcus/Documents/multiplier-02 branch: marcus/kip-76-ai-service-spin-up branch_from: origin/main command: /cook .cheese/specs/kip-76-ai-service-spin-up.mdFor a generic setup without existing benches, use worktree_strategy: create and add worktree_root: ../.cheese-worktrees; /cheese --continue derives one checkout per task from the task slug.
Document
Section titled “Document”After the slug, write a ## Document section. Open with the answer; keep every claim readable to someone who has not seen the conversation. Cover, in order, only the parts that carry signal:
- Goal. The one or two sentences that say what we are trying to achieve.
- State. What is done and verified, what is in-flight, what is untouched. Be honest about partial work; a half-finished step described accurately beats a tidy lie (Rule 9).
- Key decisions and constraints. The choices a fresh agent would otherwise re-litigate, each with a calibrated tag (
`<certain>`/`<speculating>`/`<don't know>`) and a one-line why. - Open questions and blockers. What is unresolved and what it is waiting on.
- Artifacts. A list of paths and URLs, not their contents. See
## Do not duplicate. - Suggested skills. The concrete next moves. See
## Suggested skillsfor the state-to-skill mapping. - Environment. Branch, dirty files, anything non-obvious about the working state. Redacted.
Follow the house style in ../cheese/references/formatting.md: no em-dashes, complete sentences in prose, no throat-clearing, calibrated tags on the claim.
Suggested skills
Section titled “Suggested skills”Derive next: and status: from the body’s blockers, not from optimism. See ### status: values for the gate rule.
Pick the next move from where the session actually is, name it as an easy-cheese skill with its argument, and write the same target into the slug’s next: field. Suggest the single best next step, plus the step after it when the path is obvious. When the session has two or more independent tracks that can proceed without sharing branch state, write mode: parallel, set next: tasks, and put each exact skill invocation under tasks: instead of collapsing them into one sequential next step. For several read-only follow-ups, use the inline next: list with order: instead. The map:
| Where the session is | Suggest | next: |
|---|---|---|
| Fuzzy idea, no approved spec yet | /mold |
mold |
| Research wanted before deciding or building | /briesearch <question> |
briesearch |
| Wants to think a problem through, no writes | /culture |
culture |
| Next step blocked on a human decision | surface the decision, ask direction | — (set status: gated:) |
| Compacting or stringing along, no action implied | restore orientation, wait | hold |
| Approved spec, not yet implemented | /cook <spec-path> |
cook |
| Code written, not yet hardened or reviewed | /press <slug> then /age |
press |
| Implementation done, review wanted now | /age <ref> |
age |
| Review findings in hand, fixes not applied | /cure <slug> |
cure |
| PR has review comments or failing CI | /affinage <pr> |
affinage |
| Hard bug still un-diagnosed | surface the blocker; invoke /pasteurize once ready |
— (set status: gated:) |
| Work genuinely finished | record only, no baton | done |
When the session sits mid-phase (e.g. /cook was interrupted), suggest re-entering that same phase with the slug. Tailor to the optional focus argument when the user gave one: it overrides the table if the next session is meant to do something other than advance the pipeline.
Required body sections by state
Section titled “Required body sections by state”The opening line (“/wheypoint captures just enough state for a cold reader to resume”) sets the default: compress everything that does not serve the resume. This table names the one exception and pins the minimum ## Document sections each status:/next: combination requires, so compression never eats the state a resume actually needs.
| state | required Document sections |
|---|---|
status: gated: |
## Decision dossier — per open fork: options / evidence file:line / what-each-breaks / prior leanings |
next: culture |
agenda + open-thread state |
next: cure |
findings artifact ref |
next: cook / press / age |
spec/slug pointers per existing conventions |
next: hold / done |
orientation only |
status: gated: overrides the “just enough state” compression rule for gated notes. Every open fork gets its own ## Decision dossier entry — options considered, evidence as file:line citations, what each option breaks, and any prior leaning from the session — instead of the one-line decision the compression default would otherwise leave. A resumed session with a consequential fork rebuilds its prose weighing from this dossier; see ../cheese/references/ask-user-question.md § When to structure for why an undiscussed design fork needs that weighing rather than a structured confirm.
Do not duplicate
Section titled “Do not duplicate”The point of a handoff is to be short enough to read cold. Anything already captured in a durable artifact gets a reference, not a copy:
- Specs, findings reports, research reports under
.cheese/— link by path. - PRs, issues, commits, diffs — link by URL or sha.
- Plans, ADRs, design docs — link by path or URL.
Summarise an artifact only when the summary is genuinely shorter than its pointer. Re-pasting a diff or a spec into the handoff is the failure mode this skill exists to avoid.
Redaction
Section titled “Redaction”Strip anything sensitive before writing: API keys, tokens, passwords, connection strings, and personally identifiable information. If a secret is required for the next session, reference where it lives (env var name, secret manager path), never its value.
Handoff
Section titled “Handoff”/wheypoint writes only through wheypoint.pyz commit: the canonical record, its immutable revision, and the generated projection. No Git commits, pushes, PRs, or production-code edits — durability is reported, never automatically raised. Use the host’s read-only inspection capabilities plus a write capability scoped to the durable corpus and .cheese/notes/**. The slug header keeps the shape shared/scripts/handoff.py parses and renders today; the continuity codec is additive, so parse_handoff_slug() and its callers are unchanged. End by showing the slug’s orientation line, a normal Markdown link to the projection, and repo-root-aware resumption commands. Keep the note link outside fenced code so it is clickable. The link line should match this shape: Wheypoint dropped: [.cheese/notes/<slug>.md](<absolute-note-path>).
Resume from the original repo with /cheese --continue <slug> after cd <absolute-repo-path>, or from anywhere with /cheese --continue <absolute-repo-path>/.cheese/notes/<slug>.md.