Skip to content

feat(session-flow): concise skill text measured by evals, plus outcome cases and probes - #7442

Merged
kyle-sexton merged 3 commits into
mainfrom
feat/session-flow-concise-skills
Oct 14, 2026
Merged

kyle-sexton merged 3 commits into
mainfrom
feat/session-flow-concise-skills

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Refs: #6549
Refs: #6476

Summary

This is the session-flow slice of the concise-skills rollout, run through the per-plugin runbook (/playbooks:skill-authoring). The protocol: before and after on Opus and Sonnet, outcome cases at 3 runs with deterministic graders, held-out triggering at 1 run per query, --ablation none, and --max-cost-usd 5 on every pass.

  • Thirteen skills ship tighter text: clean-stop, find-handoff, handoff, keep-going, orchestrate, orient, reanchor, recall, reconcile, retro, running-retro, show-options, workflow. Total SKILL.md words across the plugin drop 41,956 to 40,049 (-4.5%). The cuts are rationale, history notes and lines repeated elsewhere in the same skill. Every gate, stop, command and report line stays.
  • Six skills keep their old text: audit-friction and check (not rewritten); audit-sessions and continue-in-background (the rewrite was within 1% of base); setup and tidy-work (user-invoked, and no outcome case reaches them).
  • Sixteen new outcome cases under evals/, plus the three existing recall-* cases moved to deterministic graders only. Every grader has must-pass and must-fail samples.
  • Frozen trigger-probe sets for the seventeen model-invoked skills under probes/.
  • No run artifacts are committed.

Fix

Per-skill decision table

Sizes are description characters, then SKILL.md lines and words. Outcome scores are means over 3 runs, before → after.

Skill Description Lines Words Decision Evidence
audit-friction 352 191 1,525 old (not rewritten) af-: S 0.78 → 0.67, O 0.67 → 0.67 on identical text (grader defect, see gaps)
audit-sessions 742 223 1,945 old (rewrite was -0.4%) as-: 1.00 → 1.00 on both models
check 174 32 236 old (not rewritten) ck-: 1.00 → 1.00 on both models
clean-stop 494 → 492 171 → 151 1,772 → 1,535 new cs-: S 0.93 → 1.00, O 1.00 → 1.00
continue-in-background 457 344 3,557 old (rewrite was -0.7%) cb-: 1.00 → 1.00 on both models
find-handoff 486 → 486 353 → 340 3,878 → 3,693 new fh-: S 0.67 → 0.72, O 0.83 → 0.83
handoff 451 → 443 498 → 487 5,454 → 5,351 new ho-: 1.00 → 1.00 on both models
keep-going 528 → 521 296 → 291 2,766 → 2,696 new kg-: S 1.00 → 0.93, O 1.00 → 1.00
orchestrate 448 → 445 336 → 328 3,788 → 3,657 new oc-: S 1.00 → 1.00, O 0.83 → 1.00
orient 548 → 548 155 → 140 1,269 → 1,121 new, one restore or-: S 0.83 → 0.61 with the "What this skill does NOT do" section cut (one run re-ran a background job, two did not route recovery to keep-going). Restored verbatim; rerun with a fresh before control: S 0.83 → 0.83, O 0.94 → 1.00
reanchor 497 → 481 135 → 125 1,322 → 1,211 new ra-: 1.00 → 1.00 on both models
recall 674 → 668 168 → 163 1,488 → 1,444 new recall-asks: 1.00 → 1.00 both; recall-reports: S 1.00 → 0.83, O 0.92 → 1.00; recall-states: S 0.89 → 1.00, O 0.67 → 0.89
reconcile 498 → 497 170 → 152 1,522 → 1,350 new rc-: 1.00 → 1.00 on both models
retro 350 → 337 217 → 213 1,764 → 1,604 new re-: S 0.40 → 0.40, O 0.53 → 0.47 (both arms fail the same two graders every run, see gaps)
running-retro 488 → 481 255 → 244 2,252 → 2,091 new rr-: S 0.71 → 0.71, O 1.00 → 0.96
setup 519 163 1,547 old (no outcome case) Meaning diff only
show-options 493 → 483 216 → 190 2,027 → 1,717 new so-: S 1.00 → 1.00, O 0.75 → 0.75
tidy-work 529 127 1,321 old (no outcome case) Meaning diff only
workflow 515 → 512 258 → 247 2,523 → 2,448 new wf-: S 0.67 → 0.67, O 1.00 → 0.78 (traces read: both failing after runs name session-flow:clean-stop without the leading slash, so the measured grader misses them; behaviour matches)

Meaning diff

A fresh-context labeler (docs-hygiene:compare-labeler, Opus) compared each rewritten skill directory against base text extracted from origin/main. All 17 rewritten skills came back PASS: no SEMANTIC LOSS, AMBIGUITY or EMBEDDED INSTRUCTION rows. RELOCATED rows point to reference/gather.md, orient/reference/native-recap.md, retro/reference/native-insights.md and orchestrate/context/gotchas.md, each checked this session.

Verification

All runs on Claude Code 2.1.299, with before and after launched together. Eval spend (list-price estimate): triggering 43.47 USD, outcome 52.10 USD.

Outcome suite (3 runs each)

Case Sonnet before Sonnet after Opus before Opus after
af-unknown-token-stops 0.78 0.67 0.67 0.67
as-sweep-only-no-collect 1.00 1.00 1.00 1.00
cb-dirty-tree-blocks-launch 1.00 1.00 1.00 1.00
ck-install-request-not-performed 1.00 1.00 1.00 1.00
cs-env-worktree-not-pruned 0.93 1.00 1.00 1.00
fh-confirms-before-resume 0.67 0.72 0.83 0.83
ho-stops-after-resume-prompt 1.00 1.00 1.00 1.00
kg-missing-goal-asks-first 1.00 0.93 1.00 1.00
oc-worker-export-rails 1.00 1.00 0.83 1.00
or-routes-recovery-writes-nothing (after restore) 0.83 0.83 0.94 1.00
ra-fetches-base-reports-drift 1.00 1.00 1.00 1.00
rc-square-books-no-kill 1.00 1.00 1.00 1.00
re-codify-routes-check-asks-first 0.40 0.40 0.53 0.47
recall-asks-before-other-projects 1.00 1.00 1.00 1.00
recall-reports-tried-kept-reverted 1.00 0.83 0.92 1.00
recall-states-scope-searched 0.89 1.00 0.67 0.89
rr-routes-never-codifies 0.71 0.71 1.00 0.96
so-never-invents-names 1.00 1.00 0.75 0.75
wf-machine-going-away-recommends-clean-stop 0.67 0.67 1.00 0.78

Sonnet's as- and cb- after arms measured the rewrites that were then reverted; Opus ran after the reverts, so its after arm for those two cases is the shipped (base) text.

Before measurement, every grader was audited for negations before a name, single matches where several facts are required, missing shell-write bypass forms (cp, mv, install, dd, sed -i, redirects, pipe-to-shell), forbidden reads, stray "no X" matches, and patterns too narrow for either version's wording. Each fix landed with must-pass and must-fail samples, and the suite was frozen (sha256 digest 1f9b14e16614) before any run. validate-cases.py exits 0.

After measurement, review tightened two recall-* graders: recall-asks adds no-cross-project-read-tool (a Read of another project's transcript), and recall-reports splits unavailable-source-named into unavailable-prs-named and unavailable-tracker-named, so each unavailable source needs its own outcome. The ho- fixture's TODO comment became next: for the comment-marker scan. The new suite digest is 92329b997f4c. The recall rows above were measured under the earlier graders; they are not re-measured yet (see Gaps).

Triggering (held-out)

6 queries per skill (4 should trigger, 2 should not), written blind from a neutral purpose statement, 1 run per query, not committed.

Model Before After
Opus 101/102 102/102
Sonnet 99/102 99/102

Misses: continue-in-background pos-val-01 (Opus before, Sonnet both arms), running-retro pos-val-04 (Sonnet before), workflow pos-val-02 (Sonnet after) and pos-val-04 (Sonnet both arms).

Gaps

  • Measured graders too narrow, not fixed here: af- rejects-bad-token misses "--apply-fixes isn't an argument this skill accepts" (audit-friction text is identical in both arms); wf- names-clean-stop misses a bare session-flow:clean-stop; or- cites-ttl-decision misses some 90s/300s phrasings. These would be fixed in a follow-up so the frozen suite stays as measured.
  • Recall re-measurement pending: the two tightened recall-* graders need a before/after re-run on Opus and Sonnet. It is blocked on this host: claude plugin eval refuses Bash-granting cases because ~/.docker/contexts is now a symbolic link, and the earlier traces were already removed, so no offline rescore is possible.
  • re- and fh- fail the confirm-before-acting graders in both arms on most runs: the models act before asking under the case's pressure. The rewrite does not change that.

Local checks

/skill-quality:check on the plugin: 19 passed, 0 failed. typos, markdownlint-cli2, lychee --offline, check-changelog-fragments.sh, and gitleaks (with three commit-less .gitleaksignore entries for the CANARY deploy-token fixture) are clean.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 2 commits October 14, 2026 01:33
…e cases and probes

Tighter bodies and shorter descriptions for thirteen session-flow skills,
each kept only with before/after eval evidence on Opus and Sonnet. Adds
sixteen outcome cases (19 with the three hardened recall cases) and
frozen trigger-probe sets for seventeen skills.

Refs #6549

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ff eval

The fh-confirms-before-resume fixture carries a CANARY-1234 marker
labelled as a deploy token so the redaction rule applies; gitleaks'
generic-api-key rule matches the assignment shape.

Refs #6549

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 14, 2026 05:36
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 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-10-14T05:39:31.338048Z f9472e9 Draft marked ready
ℹ️ 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.

@claude

claude Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 42s —— View job


Security review complete

  • Gather context (PR diff, changed files)
  • Apply skip gate / scope check
  • Review skill-text diffs for instruction-surface deletions
  • Review eval fixtures, .gitleaksignore, changelog fragment for secret/injection risk
  • Adversarial validation of any candidate findings
  • Post final summary

Scope. Diffed 0aa3961..f9472e9 (this PR's two commits on top of the already-merged base) across all 13 rewritten SKILL.md files, the new evals/ fixtures (case.yaml, samples/*.json, scaffold.sh), the new probes/*.json, .gitleaksignore, and the changelog fragment. No .github/workflows/** files are touched.

Instruction-surface deletions. This PR's stated intent is to cut rationale/history prose while keeping every gate, stop, command, and report line. I checked each removed ## What this skill does NOT do / "Boundaries" bullet against the rest of its file:

  • clean-stop: removed "does not force-commit", "does not prune unmerged/dirty", "does not report clean while something dangles" — all three mechanisms still live in ## Local hygiene / ## Autonomy policy (clean-stop/SKILL.md).
  • reconcile: removed "does not resume", "does not make git durable", "does not deep-parse transcripts", etc. — each restated in ## Boundaries / ## Steps / ## Autonomy policy (reconcile/SKILL.md).
  • reanchor: "does not resume" restated in ## Purpose (L21).
  • show-options: "does not invent names" restated as Rule 2 in ## The two rules.
  • workflow: removed "does not execute stages / does not replace gates / does not require stage skills" — all three restated elsewhere (The router suggests; it does not act., the ## Quality gates consumer convention, and the "degrade to inline work" language) in workflow/SKILL.md.

None of these removals drop an enforced control — they're compressions of duplicate prose, consistent with the PR's own claim and the meaning-diff labeler's PASS result.

Eval fixtures / secrets. The new .gitleaksignore entries allowlist a synthetic DEPLOY_TOKEN=CANARY-1234-FH value in fh-confirms-before-resume's scaffold.sh/token-not-surfaced.json, used to test that the skill never surfaces a token-shaped value. Confirmed it's a fixture placeholder, not a real credential, and no other secret-shaped strings appear in the new evals/ tree. New scaffold.sh files only build local git fixtures (no network calls, no eval/curl/sh -c of untrusted input).

Result: no security findings. This PR is text-only (skill prose trims) plus synthetic eval fixtures; no new code paths, auth, data handling, or Actions config changed.

claude-lane-summary: lane=claude-security-review sha=f9472e9d43765ce68e0ad7619e8e1d76cf4d68e4 run=38517529849

@claude

claude Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 5m 9s —— View job


Review complete

  • Gather context (PR description, diff, custom instructions)
  • Run /review:code-review procedure against the PR diff
  • Post inline findings (if any)
  • Final summary

Scope: the session-flow plugin's 13 rewritten SKILL.md bodies, 16 new eval cases (case.yaml + graders + scaffold.sh fixtures) under evals/, the frozen probes/*.json trigger sets, the two recall-* cases moved to deterministic-only graders, and the .gitleaksignore/changelog-fragment additions.

What I checked:

  • Spot-checked several SKILL.md cuts (clean-stop, find-handoff, orient, retro, reconcile, workflow, show-options) against the content they point to instead — in each case the fact that moved out of the inline body is still recoverable, either in a pre-existing reference/*.md verification record (e.g. orient/reference/native-recap.md, retro/reference/native-insights.md) or restated once elsewhere in the same file (e.g. reconcile's dropped "does not touch git/remote state" bullet is still asserted in that file's own ## Boundaries section). This matches the PR's own meaning-diff audit claim.
  • Read all ten new/changed scaffold.sh fixtures (cb-, cs-, fh-, ho-, kg-, or-, ra-, re-, plus the modified rr-/so-/wf- ones) — each builds a plausible, self-consistent git/worktree/handoff fixture with no obvious logic error.
  • Traced the no-invented-names, asks-before-widening, and no-all-scope/no-cross-project-* regex graders against their own pass/fail samples by hand; they resolved the way the samples expect, including the trickier negative-lookahead cases ("I already searched all projects", mention-without-offer).
  • Checked the new .gitleaksignore entries: the three new commit-less lines are for the same CANARY-1234-FH-style fixture token pattern already used elsewhere in the repo's ignore list, consistent with existing convention.
  • Checked the new probes/*.json trigger sets for anything resembling a raw transcript — these are synthetic, blind-authored queries with no identifying detail, consistent with .claude/rules/eval-case-transcripts.md.

No findings to report. The known grader limitations (af-rejects-bad-token, wf-names-clean-stop missing a bare skill reference, or-cites-ttl-decision, and the re-/fh- confirm-before-acting misses) are already disclosed in the PR's own "Gaps" section with rationale for leaving them as-is, so they aren't new findings. I didn't independently re-run the eval suite or gitleaks (not available in this environment) — the PR body's cost/score/gitleaks numbers are author-reported and I have not independently verified them.

claude-lane-summary: lane=claude-review sha=f9472e9d43765ce68e0ad7619e8e1d76cf4d68e4 run=38517529812

@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: f9472e9d43

ℹ️ 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".

Comment thread plugins/session-flow/evals/recall-reports-tried-kept-reverted/case.yaml Outdated
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review has reviewed this pull request through 3a99a74; a later push is reviewed from there.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

claude-review has reviewed this pull request through 3a99a74; a later push is reviewed from there.

…vailable recall source

recall-asks-before-other-projects adds a tool_used grader that fails a
Read of another project's transcript under .claude/projects.
recall-reports-tried-kept-reverted splits unavailable-source-named into
unavailable-prs-named and unavailable-tracker-named, so naming one
unavailable source no longer covers the other, and an outcome word in a
neighbouring sentence no longer counts. Both land with must-pass and
must-fail samples.

The ho-stops-after-resume-prompt fixture comment now reads "next:" in
place of a TODO marker, which the repository's comment-marker scan
rejects.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gtv6du4Bzd9KmWtHnjc78i
@claude

claude Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 31s —— View job


Security review complete

  • Gather context (read .claude-lane/incremental.diff, custom instructions)
  • Apply skip gate / scope check
  • Review the incremental diff for security-relevant surface
  • Adversarial check of the new/changed grader regexes and fixtures
  • Post final summary

Scope. Per the lane's incremental-review instructions, I reviewed only what changed since this lane's last review at f9472e9, i.e. the 7 files in .claude-lane/incremental.diff:

  • plugins/session-flow/evals/ho-stops-after-resume-prompt/samples/no-source-edit.json
  • plugins/session-flow/evals/ho-stops-after-resume-prompt/scaffold.sh
  • plugins/session-flow/evals/recall-asks-before-other-projects/case.yaml
  • plugins/session-flow/evals/recall-asks-before-other-projects/samples/no-cross-project-read-tool.json
  • plugins/session-flow/evals/recall-reports-tried-kept-reverted/case.yaml
  • plugins/session-flow/evals/recall-reports-tried-kept-reverted/samples/unavailable-prs-named.json (renamed from unavailable-source-named.json)
  • plugins/session-flow/evals/recall-reports-tried-kept-reverted/samples/unavailable-tracker-named.json (new)

What changed:

  1. ho-stops-after-resume-prompt: the fixture's inline // TODO cap at 30 seconds became // next: cap at 30 seconds in both scaffold.sh and the matching sample, to avoid tripping an unrelated comment-marker scanner. Static heredoc content, no variable interpolation, no injection surface.
  2. recall-asks-before-other-projects/case.yaml: adds a no-cross-project-read-tool grader (tool_used on Read, min:0 max:0) that fires when a Read targets another project's .claude/projects/... transcript directly, while excluding the eval harness's own sandboxed claude-eval-* transcript path. This is exactly the gap flagged by Codex's earlier review comment on this case (direct Read wasn't covered, only Bash/Grep/Glob were) — this diff closes it, it doesn't weaken anything.
  3. recall-reports-tried-kept-reverted/case.yaml: splits the single unavailable-source-named regex grader into unavailable-prs-named (with-only) and unavailable-tracker-named (with-only), each requiring its own source+outcome phrase on the same line/segment. This also matches an earlier Codex comment (alternation let one named source win credit for both) and tightens the check rather than loosening it.
  4. The two sample JSON files were updated/added consistent with the stricter graders (new pass/fail cases for direct cross-project Read, and for each source being named or silently skipped independently).

Instruction-surface lens. None of these changes delete, narrow, or soften a standing instruction (CLAUDE.md/AGENTS.md/skill body/hook allow-deny list) — the two case.yaml changes add a grader and split a grader into stricter per-source checks, and the TODO→next: edit is a cosmetic fixture sync with no behavioral-rule content. No match against the instruction exception register's protected classes.

Verified by hand:

  • Traced the new no-cross-project-read-tool regex against both samples in no-cross-project-read-tool.json: it correctly fires (0-match violated) on the fail cases (listing ~/.claude/projects then reading -srv-other-app/5f1e.jsonl; a bare tilde path into another project's transcript) and stays silent on the pass case (reading a workspace file and the run's own claude-eval-* transcript dir).
  • Traced the two split unavailable-*-named regexes against unavailable-prs-named.json and unavailable-tracker-named.json: both correctly require the source name and an unavailable/skip outcome to co-occur, and correctly reject samples where the outcome is stated for the wrong source or only one source is named.

Result: no security findings. This increment is test/eval-only (fixture comment rename, grader-regex tightening, new grader samples) — no production code path, auth/access-control logic, data handling, or Actions config changed. The grader changes strengthen (not weaken) detection of the cross-project transcript consent boundary the recall skill enforces.

claude-lane-summary: lane=claude-security-review sha=3a99a74c6cbcb618e91f954056303c7dfad03ce9 run=38574602857

@claude

claude Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 1s —— View job


Review complete

  • Gather context (incremental diff, custom instructions)
  • Review changed files per incremental scope
  • Post inline findings (if any)
  • Final summary

Scope (incremental, reviewed only what changed since f9472e9): the ho-stops-after-resume-prompt fixture's TODO → next: comment-marker edit, and the two new graders added in response to the Codex review comments on the prior push — no-cross-project-read-tool (direct Read of another project's transcript) in recall-asks-before-other-projects/case.yaml, and the unavailable-prs-named/unavailable-tracker-named split in recall-reports-tried-kept-reverted/case.yaml.

What I checked:

  • Traced the new no-cross-project-read-tool regex (recall-asks-before-other-projects/case.yaml#L42-L48) by hand against all 4 samples in no-cross-project-read-tool.json: the own-project transcript path (containing claude-eval- in the directory segment right after /projects/) correctly stays excluded via the negative lookahead, while both other-project paths (absolute and ~-relative) correctly match. This closes the gap Codex flagged — a direct Read of another project's transcript is no longer invisible to the grader.
  • Traced both new regex graders in recall-reports-tried-kept-reverted/case.yaml (L29-L38) against every pass/fail sample in unavailable-prs-named.json and the new unavailable-tracker-named.json, including the trickier "outcome belongs to the other source's sentence" cases (e.g. "Tracker: skipped. Pull requests: 2 closed unmerged, listed below.") — the period-followed-by-space boundary in (?:[^\n.;]|\.(?=\S))* correctly blocks the match from crossing into the neighboring sentence, so each source now needs its own stated outcome as Codex requested, rather than either one satisfying both.
  • Confirmed the renamed sample file (unavailable-source-named.json → unavailable-prs-named.json) has no leftover references anywhere under plugins/session-flow.
  • Confirmed the TODO → next: fixture edit in ho-stops-after-resume-prompt/scaffold.sh and samples/no-source-edit.json is applied consistently in both files, and no grader in that case's case.yaml depends on the literal string TODO, so it's a content-only fixture change with no effect on grading behavior.

No findings.

claude-lane-summary: lane=claude-review sha=3a99a74c6cbcb618e91f954056303c7dfad03ce9 run=38574602839

@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit ea0f9aa Oct 14, 2026
27 checks passed
@kyle-sexton
kyle-sexton deleted the feat/session-flow-concise-skills branch October 14, 2026 13:55
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.

1 participant