Skip to content

perf(session-flow): move handoff WIP-commit mechanics to a reference file - #12869

Merged
kyle-sexton merged 3 commits into
mainfrom
host-run/12657-handoff-skill-cut
Nov 3, 2026
Merged

kyle-sexton merged 3 commits into
mainfrom
host-run/12657-handoff-skill-cut

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Closes #12657

Summary

The /session-flow:handoff hub loaded the WIP commit's refusal checks, staging steps and record rules, and the /export verification record, on every invocation. Only a pause with wip_commit on needs the first, and the second is provenance. This PR moves both word for word into reference files read on demand. It is the third progressive-disclosure cut under #12243 and follows the #12387 recipe.

Fix

  • reference/wip-commit.md holds the moved refusal checks, staging, hook-rejection path and record rules. The hub keeps when the commit applies, how the setting resolves (its ${CLAUDE_PLUGIN_ROOT} and ${user_config.wip_commit} substitutions expand only in SKILL.md), and a pointer.
  • reference/export-verification.md holds the /export verification record. The prompt-only checklist bullet that cited it now links the file.
  • A new reference index in the hub has a row for each reference file.
  • Hub body (SKILL.md with frontmatter stripped): 36,785 bytes on main, 34,609 bytes on this branch.
  • No case read the moved WIP-commit text, so the new ho-wip-commit-on-pause case turns wip_commit on in its scaffold. It checks for one local commit staged with --pathspec-from-file, and no push.

Verification

  • awk frontmatter strip piped to wc -c on both copies printed 36785 and 34609.

  • /docs-hygiene:compress compare (fresh compare-labeler, before against after): VERDICT PASS, with no SEMANTIC LOSS and no AMBIGUITY rows. It confirmed that no ${CLAUDE_PLUGIN_ROOT} or ${user_config.*} substitution moved out of SKILL.md.

  • Citations: a repo-wide grep found no external citation of the moved text. reference/config.md:14 cites the "WIP commit on an explicit pause" heading, which stays in the hub.

  • /evals:validate (validate-cases.py, check-matchers.py) reports no FAIL for the suite.

  • Paired ho-* eval plus a negative control, preregistered on perf(session-flow): cut the handoff skill body through progressive disclosure #12657 before the first paid run.

    • Setup: Claude Code 2.1.317, claude-opus-5-5, subscription login, capped scopes.
    • Command per case group: claude plugin eval <copy> --case <glob> --runs 2 -j 2 --scaffold --ablation none --allow-tools Bash Write Edit --keep-temp.
    • ho-todowrite-renders-list ran in its own invocation with CLAUDE_CODE_ENABLE_TASKS=0, as its case requires.
    • Each arm's per-case results were merged into one file before the compare.
    • Arms: before is this branch's copy with main's skills/handoff swapped in. Degraded is the before copy with the handoff SKILL.md body deleted (frontmatter kept). Before and after ran together; a second before run and degraded ran together.
    • Case defect, fixed before counting: the first ho-wip-commit-on-pause run had no origin/HEAD in its scaffold, so main's skill correctly refused the commit (unknown default branch). The commit grader also matched a Bash description field. Commit 5d0fbd7 fixes the scaffold and anchors the graders to the command. All four arms then reran that case; only the rerun counts.
    Arm Mean case score run-validity.py --runs 2 --scaffolded
    before 1.00 (5/5) VALID (warnings: skill fired, models)
    after 1.00 (5/5) VALID (warnings: skill fired, models)
    before, control pair 1.00 (5/5) VALID (warnings: skill fired, models)
    degraded 0.49 (0/5) INVALID (2 permission denials), run with --own-copy-search-warns
    • noise-report, after against before at margin 0.05: change +0.00 (interval +0.00 to +0.00), non-inferior.
    • noise-report, degraded against the control-pair before: change -0.51 (interval -0.68 to -0.34), case drops on four of five cases.
    • The two denials sit in ho-task-tools-recreate-calls and ho-stops-after-resume-prompt. With those cases left out, the mean still falls from 1.00 to 0.50, past the preregistered 0.15. The suite detects a loss, so the cut is measurable. ho-wip-commit-on-pause falls from 1.00 to 0.67.
    • The skill-fired warning is expected. Every case opens with the /session-flow:handoff slash command, which loads the skill without a Skill tool call, and no case has a skill-fired grader.

Related

🤖 Generated with Claude Code

…file

The /session-flow:handoff hub loaded the WIP commit's refusal checks,
staging steps and record rules, and the /export verification record, on
every invocation, though only a pause with wip_commit on needs the first
and the second is provenance. Both move verbatim to reference files; the
hub keeps when the commit applies, how the setting resolves, and a
pointer, plus a reference index with a row per file.

Body bytes (frontmatter stripped): 36,785 on main, 34,609 here.

No case read the moved WIP-commit text, so ho-wip-commit-on-pause turns
wip_commit on in the scaffold and checks for one local commit staged
with --pathspec-from-file and no push.

Refs: #12657

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-03T16:35:00.623106Z 6eee881 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6eee881930

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@kyle-sexton

Copy link
Copy Markdown
Member Author
  • verify skipped by kyle-sexton for this run: verify would only repeat CI's suites; the change is skill markdown plus one eval case, already checked by validate-cases and the pre-push check-affected hook

The first run on main's skill refused the WIP commit, correctly: the
scaffold had no origin/HEAD, and an unknown default branch is a refusal
check. The scaffold now points origin/HEAD at main. The graders also
matched a Bash call's description field; they now read only its command.

Refs: #12657

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed 5d0fbd7246da2cbc4b2cff60235ba3410ecdc580: read 3 of 3 changed file(s); 0 finding(s), 0 as inline comments.

Code review (incremental): PR #12869, a449738 → 5d0fbd7

Scope. I read every hunk of the 3 files in .claude-lane/incremental.diff: case.yaml, samples/wip-commit-made.json and scaffold.sh under plugins/session-flow/evals/ho-wip-commit-on-pause/. I used the full diff and reference/wip-commit.md only for context.

No new findings. Both findings from round 2 are fixed at this head.

  1. Scaffold gave no default branch (was blocking): fixed. scaffold.sh:19-21 now creates refs/remotes/origin/main and points origin/HEAD at it before checking out feat/retry-backoff. That gets the case past each refusal check in reference/wip-commit.md:9-18:

    • origin HEAD resolves to main, which is not the branch HEAD is on.
    • No sequencer operation is in progress.
    • HEAD is not detached.
    • Nothing is staged.

    A model that follows the skill should now commit. The owner's settled thread on these lines agrees.

  2. Graders not tied to the command field (was advisory): fixed.

    • All three input_match patterns now start at "command":".
    • Their middle sections consume only non-quote characters or JSON escape pairs ((?:[^"\\\n]|\\.)), so a match cannot run past the end of the command string into another field such as description.
    • This matches the compact-JSON form the validator documents and the "command":"(?:[^"\\]|\\.)*?… pattern in test_check_matchers.py.
    • Because escapes are consumed in pairs from the start of the string, the (?!\\n|;|&&|\|) lookahead still lines up with the JSON-escaped newline.
    • Two new samples cover the change: a pass sample whose path is in escaped quotes (git -C \"/tmp/case dir\" commit …), and a fail sample where only the description says "commit" (git rev-parse --git-path MERGE_HEAD, a call the refusal checks really make).
    • The max-0 no-push grader no longer fails a run whose description mentions a push.

The PR description matches this head again. The head is 5d0fbd7, the commit the description names as the one that fixed the scaffold and graders, so the earlier mismatch note is resolved.

Closing issue #12657. The third "Done when" criterion (a paired ho-* round, VALID and non-inferior, with a case that reads the moved text) now has a case that can show it. The eval scores, VALID verdicts and noise reports are the author's claims; I did not verify them.

Verification. I ran nothing. I checked the regex behaviour against the samples by reading them; I did not execute the matchers.

Spend. The case spends prepaid API or subscription usage each time it runs. That is not a hold.

Prior findings. This is round 3 of a cap of 3; the cap does not apply. Neither round-2 finding is restated, because the code each one pointed at is fixed.

@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 5d0fbd7246da2cbc4b2cff60235ba3410ecdc580: read 3 of 3 changed file(s); 0 finding(s), 0 as inline comments.

Security review: PR #12869 (incremental, a449738 → 5d0fbd7)

No security issues found.

This is an incremental review. I read every hunk of the 3 files in scope. None of them matches a TRUSTED PATHS glob, and none touches a trust control, a merge hold, an instruction surface or a plugin manifest.

  • plugins/session-flow/evals/ho-wip-commit-on-pause/case.yaml: the three tool_used grader regexes are now anchored to the "command":"..." JSON field. They no longer match text anywhere in the serialized tool input. These graders are static eval data. They score a run and gate nothing a credential or merge decision depends on. The change also makes the graders stricter: a description field that mentions commit no longer satisfies wip-commit-made.
  • samples/wip-commit-made.json: this file is static fixture data. It adds a quoted-path pass sample and a fail sample where only the description mentions a commit. Nothing in it is executed.
  • scaffold.sh: the scaffold now runs git update-ref refs/remotes/origin/main HEAD and git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main. Both commands only create local refs in the throwaway eval repo. They make no network call, add no remote and take no outside input.

Prior findings. This lane's earlier summary, at a449738, reported 0 findings. Nothing in this diff changes that, so nothing is re-posted.

critical-findings: 0

@kyle-sexton
kyle-sexton added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit f138b99 Nov 3, 2026
69 of 71 checks passed
@kyle-sexton
kyle-sexton deleted the host-run/12657-handoff-skill-cut branch November 3, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(session-flow): cut the handoff skill body through progressive disclosure

1 participant