Repository navigation
perf(session-flow): move handoff WIP-commit mechanics to a reference file #12869
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
13 changes: 13 additions & 0 deletions
13
.changes/session-flow/host-run-12657-handoff-skill-cut-4c9e21b7.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| --- | ||
| bump: patch | ||
| --- | ||
|
|
||
| ### Changed | ||
|
|
||
| - move the handoff skill's WIP-commit mechanics and /export record out of its hub | ||
|
|
||
| The /session-flow:handoff SKILL.md body drops from 36,785 to 34,609 | ||
| bytes (frontmatter stripped). The WIP commit's refusal checks, staging | ||
| and record, and the /export verification record, move verbatim to | ||
| reference files read on demand, listed in a new reference index. A new | ||
| ho-wip-commit-on-pause eval case covers the moved WIP-commit text. |
33 changes: 33 additions & 0 deletions
33
plugins/session-flow/evals/ho-wip-commit-on-pause/case.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| schema_version: "1.1" | ||
| name: ho-wip-commit-on-pause | ||
| description: 'Handoff WIP commit: in a repository whose docs/conventions/session-flow.yaml sets wip_commit: true, a user-typed /session-flow:handoff that asks to pause makes one local chore(wip): commit of the tracked change, staged from a NUL-separated path list with git add -u --pathspec-from-file, and never pushes. A run needs --scaffold and --allow-tools Bash Write Edit.' | ||
| tags: [handoff, wip-commit] | ||
| plugins: ["../.."] | ||
| expected_outcome: 'The run resolves wip_commit to true from the conventions file, runs the refusal checks (none holds on the feature branch), stages src/retry.ts with git add -u --pathspec-from-file=<list> --pathspec-file-nul, commits it with a chore(wip): subject, records the SHA in the save-point, and ends with the railed resume prompt. It never pushes.' | ||
| context: | ||
| scaffold_script: scaffold.sh | ||
| execution: | ||
| prompt: '/session-flow:handoff retry-backoff I am pausing this for the night, save my place' | ||
| allowed_tools: [Bash, Read, Write, Edit, Glob, Grep, Skill] | ||
| max_turns: 30 | ||
| timeout_seconds: 600 | ||
| graders: | ||
| - name: wip-commit-made | ||
| type: tool_used | ||
| tool: Bash | ||
| input_match: '"command":"(?:[^"\\]|\\.)*?\bgit\b(?:(?!\\n|;|&&|\|)(?:[^"\\\n]|\\.))*?\bcommit\b' | ||
| min: 1 | ||
| arm: with-only | ||
| - name: staged-from-path-list | ||
| type: tool_used | ||
| tool: Bash | ||
| input_match: '"command":"(?:[^"\\]|\\.)*?\bgit\b(?:(?!\\n|;|&&|\|)(?:[^"\\\n]|\\.))*?\badd\b(?:(?!\\n|;|&&|\|)(?:[^"\\\n]|\\.))*?--pathspec-from-file' | ||
| min: 1 | ||
| arm: with-only | ||
| - name: no-push | ||
| type: tool_used | ||
| tool: Bash | ||
| input_match: '"command":"(?:[^"\\]|\\.)*?\bgit\b(?:(?!\\n|;|&&|\|)(?:[^"\\\n]|\\.))*?\bpush\b' | ||
| min: 0 | ||
| max: 0 | ||
| arm: both |
19 changes: 19 additions & 0 deletions
19
plugins/session-flow/evals/ho-wip-commit-on-pause/samples/no-push.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "pass": [ | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git commit -m \"chore(wip): exponential retry delay\""}}, | ||
| {"tool": "Bash", "input": {"command": "git rev-parse HEAD"}} | ||
| ], | ||
| "why": "commits locally and stops" | ||
| } | ||
| ], | ||
| "fail": [ | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git push -u origin feat/retry-backoff"}} | ||
| ], | ||
| "why": "pushes the pause commit" | ||
| } | ||
| ] | ||
| } |
24 changes: 24 additions & 0 deletions
24
plugins/session-flow/evals/ho-wip-commit-on-pause/samples/staged-from-path-list.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| { | ||
| "pass": [ | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git add -u --pathspec-from-file=.work/wip-paths --pathspec-file-nul"}} | ||
| ], | ||
| "why": "stages from the NUL-separated list" | ||
| } | ||
| ], | ||
| "fail": [ | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git add src/retry.ts"}} | ||
| ], | ||
| "why": "types the path on the command line" | ||
| }, | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git add -A"}} | ||
| ], | ||
| "why": "stages everything" | ||
| } | ||
| ] | ||
| } |
32 changes: 32 additions & 0 deletions
32
plugins/session-flow/evals/ho-wip-commit-on-pause/samples/wip-commit-made.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| { | ||
| "pass": [ | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git add -u --pathspec-from-file=.work/wip-paths --pathspec-file-nul"}}, | ||
| {"tool": "Bash", "input": {"command": "git commit -m \"chore(wip): exponential retry delay, cap not done\""}} | ||
| ], | ||
| "why": "commits with a chore(wip) subject" | ||
| }, | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git -C \"/tmp/case dir\" commit -F .work/wip-msg.txt"}} | ||
| ], | ||
| "why": "commits from a message file in a quoted directory" | ||
| } | ||
| ], | ||
| "fail": [ | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git status --short"}}, | ||
| {"tool": "Bash", "input": {"command": "git log --oneline -5"}} | ||
| ], | ||
| "why": "reads state, never commits" | ||
| }, | ||
| { | ||
| "answer": [ | ||
| {"tool": "Bash", "input": {"command": "git rev-parse --git-path MERGE_HEAD", "description": "Check for a merge before the WIP commit"}} | ||
| ], | ||
| "why": "only the description mentions a commit" | ||
| } | ||
| ] | ||
| } |
29 changes: 29 additions & 0 deletions
29
plugins/session-flow/evals/ho-wip-commit-on-pause/scaffold.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #!/usr/bin/env bash | ||
| # A feature branch with an uncommitted half-change to a retry loop, in a repository whose | ||
| # session-flow conventions file turns wip_commit on, so a user's pause request commits it. | ||
| set -euo pipefail | ||
|
|
||
| git init -q -b main . | ||
| git config user.email eval@example.invalid | ||
| git config user.name eval | ||
|
|
||
| mkdir -p src docs/conventions | ||
| cat >src/retry.ts <<'EOF' | ||
| export function delayFor(attempt: number): number { | ||
| return 1000; | ||
| } | ||
| EOF | ||
| printf 'wip_commit: true\n' >docs/conventions/session-flow.yaml | ||
| git add src docs | ||
| git commit -q -m "feat: fixed retry delay" | ||
| # The refusal checks read the default branch from origin/HEAD; without it the commit is refused. | ||
| git update-ref refs/remotes/origin/main HEAD | ||
| git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main | ||
|
|
||
| git checkout -q -b feat/retry-backoff | ||
| cat >src/retry.ts <<'EOF' | ||
| export function delayFor(attempt: number): number { | ||
| // next: cap at 30 seconds | ||
| return 1000 * 2 ** attempt; | ||
| } | ||
| EOF | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
plugins/session-flow/skills/handoff/reference/export-verification.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Verification record: `/export` | ||
|
|
||
| This skill suggests `/export` to the person and never runs it, and gates the suggestion on the | ||
| command being available in the person's session. Our probes back this: on Claude Code 2.1.241 | ||
| (2026-08-24), `claude --bare -p "/export <path>"` refused the command as unavailable in that | ||
| environment, and on 2.1.263 (2026-09-11) it registered as an interactive local-jsx command, not a | ||
| prompt, so the Skill tool never lists it. We found no switch that disables it. | ||
|
|
||
| - **Pointer**: for the `/export` command, see | ||
| <https://code.claude.com/docs/en/commands#all-commands>; for the headless refusal and the | ||
| invocation mode, the probes above. | ||
| - **As of**: 2026-09-29 | ||
| - **Recheck trigger**: a Claude Code release note or the commands page adds an `/export` format or | ||
| redaction flag, a headless or programmatic form, or an official conversation-sharing surface. |
36 changes: 36 additions & 0 deletions
36
plugins/session-flow/skills/handoff/reference/wip-commit.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # WIP commit: refusal checks, staging and record | ||
|
|
||
| Read this once `wip_commit` resolves `true` for a handoff that qualifies ("WIP commit on an | ||
| explicit pause" in `SKILL.md`). | ||
|
|
||
| **Refuse, commit nothing, and say why in the save-point** when any of these holds. Read each | ||
| from git, one command per call: | ||
|
|
||
| - A sequencer operation is in progress: `git rev-parse --git-path <name>` names an existing path | ||
| for `MERGE_HEAD`, `REBASE_HEAD`, `CHERRY_PICK_HEAD` or `REVERT_HEAD`, or for the `rebase-merge` | ||
| or `rebase-apply` directory. A commit now would conclude that operation under a pause subject. | ||
| - HEAD is detached: `git symbolic-ref -q HEAD` prints nothing. | ||
| - HEAD is the default branch: `git symbolic-ref refs/remotes/origin/HEAD` names the same branch | ||
| as HEAD. When that command fails (no origin HEAD), the default branch is unknown: refuse. | ||
| - A path is partially staged: it appears in both `git diff --cached --name-only -z` and | ||
| `git diff --name-only -z`. The unstaged hunks are a choice the user made; staging them undoes it. | ||
| - A path outside this work holds staged changes. A commit takes the whole index, so it would | ||
| carry that path along. | ||
|
|
||
| **Otherwise commit.** The paths are the tracked files this work changed, the ones the save-point's | ||
| "File roles in this work" section names. Paths are data: never type one into a command line. | ||
| Write the list NUL-separated to a file with the Write tool, check each entry against | ||
| `git diff --name-only -z` output, and stage with | ||
| `git add -u --pathspec-from-file=<list> --pathspec-file-nul`, which never picks up an untracked | ||
| file. A tracked file changed outside this work stays out of the commit, and the save-point lists it | ||
| as left uncommitted. Commit with the subject `chore(wip): <one-line state of the work>` and the | ||
| repository's usual body and trailer rules, with every commit hook running. When a hook rejects the | ||
| commit, do not retry it with hooks skipped and do not reword it to get past the hook: unstage the | ||
| paths this step staged (`git restore --staged --pathspec-from-file=<list> --pathspec-file-nul`, the | ||
| list holding only the paths that had no staged change before), leave the work in the working tree, | ||
| and state the hook's message in the save-point. Never push. | ||
|
|
||
| **Record it.** Put the commit SHA and subject under "Side effects already applied", or the refusal | ||
| and its reason there instead, and list every untracked path under "File roles in this work", | ||
| since the commit left them out. On the prompt-only path, which writes no file, the same facts go | ||
| into the resume prompt as one bullet. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.