Skip to content

feat: add experimental Session Hooks lab - #22

Merged
runesleo merged 2 commits into
mainfrom
feat/session-hooks-lab
Oct 18, 2026
Merged

runesleo merged 2 commits into
mainfrom
feat/session-hooks-lab

Conversation

@runesleo

Copy link
Copy Markdown
Owner

What

Adds an experimental Session Hooks lab (labs/session-hooks/) with three standard-library-only Claude Code hooks:

  • session_title_nudge (UserPromptSubmit) — reminds the model to retitle the session when the main thread changes.
  • archive_readiness_nudge (Stop) — asks every final reply to end with one "archive check" line judged on the whole conversation; never archives anything itself.
  • needs_me_surface (SessionStart + UserPromptSubmit) — surfaces unchecked items from a "needs my decision" markdown checklist into model context with fingerprint dedupe, pagination and a four-way triage whose counts must add up.

Bilingual READMEs, example settings/checklist (synthetic data), and 20 tests. Main README, CHANGELOG (Unreleased) and lab CI wired.

Review

  • Independent Codex review: first pass FIX FIRST (3 findings: install cp could overwrite an existing checklist; resume dropped later pages; concurrent cleanup could swallow the title nudge) → fixed with regression tests in 24ae45b → second pass SHIP.
  • Privacy scan: zero hits (paths, usernames, hostnames, internal IPs, emails, token shapes, wallet addresses).
  • ./scripts/verify.sh passes; 20/20 lab tests pass.

Not verified

Not exercised inside a live Claude Code host in this PR (the hooks are generalized from versions in daily use). background_tasks in the Stop payload may not exist on every Claude Code version — documented in the README.

🤖 Generated with Claude Code

runesleo and others added 2 commits October 18, 2026 20:17
Three independent Claude Code hooks, Python stdlib only:
- session_title_nudge (UserPromptSubmit): remind the model to retitle the
  session with 2-4 keywords when its main thread moves, at most once per
  interval; never renames anything itself.
- archive_readiness_nudge (Stop): require one archive-check line judging
  the whole session at the end of every final answer; never archives.
- needs_me_surface (SessionStart + UserPromptSubmit): inject unchecked
  items of one "needs me" checklist with per-session fingerprint dedup,
  pagination, and a four-bucket accounting rule; read-only, fails to
  UNKNOWN instead of a false empty list.

Bilingual READMEs, example settings and checklist, synthetic-stdin tests
wired into lab CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Install: never overwrite an existing needs-me checklist or symlink;
  re-running the install snippet is now safe.
- needs_me_surface: SessionStart persists a fresh cursor, so later pages
  are no longer silently dropped after a session resumes.
- session_title_nudge: stale-state cleanup is best effort per file and
  runs after the reminder is printed, so a concurrent delete can no
  longer swallow and suppress a nudge. Same hardening in needs_me_surface.
- Regression tests for all three (fail on the previous code).

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

chatgpt-codex-connector Bot commented Oct 18, 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-18T12:51:19.437436Z 24ae45b 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.

@runesleo
runesleo merged commit c218fd8 into main Oct 18, 2026
1 check passed
@runesleo
runesleo deleted the feat/session-hooks-lab branch October 18, 2026 12:49

@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: 24ae45b76c

ℹ️ 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 on lines +77 to +79
for task in payload.get("background_tasks") or []:
if isinstance(task, dict) and task.get("status") in _ACTIVE:
return {"decision": "block", "reason": _msg(RUNNING)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject ready while session crons remain

When the session has a scheduled wakeup but no background task, this loop accepts Archive check: ready, so the user can be told the session is safe to archive even though session-scoped work is still pending. Claude Code's Stop input schema provides session_crons specifically alongside background_tasks to distinguish a completed session from one waiting to wake up; inspect that array before accepting the ready verdict.

AGENTS.md reference: AGENTS.md:L10-L10

Useful? React with 👍 / 👎.

data = json.loads(sys.stdin.read() or "{}")
if not isinstance(data, dict):
return
sid = str(data.get("session_id") or "").strip()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve custom session titles using the hook input

When a user previously named a session with /rename or --name without discussing that action in the conversation, this hook discards the session_title field and gives the model no reliable way to follow its instruction to ask before renaming. The UserPromptSubmit schema supplies session_title whenever a custom title exists, so the hook should use it to suppress or qualify the nudge; otherwise a manually chosen title can be overwritten without confirmation.

AGENTS.md reference: AGENTS.md:L10-L10

Useful? React with 👍 / 👎.

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