Skip to content

fix(codex): survive plugin cache refreshes - #240

Merged
kengio merged 14 commits into
mainfrom
fix/codex-hook-cache-lifecycle
Aug 28, 2026
Merged

fix(codex): survive plugin cache refreshes#240
kengio merged 14 commits into
mainfrom
fix/codex-hook-cache-lifecycle

Conversation

@kengio

@kengio kengio commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • switch Codex lifecycle manifests from the versioned cache Python bridge to the installed CLI hook runner
  • remove the obsolete codex-hook.py bridge and raise the CLI floor to 3.4.25
  • reuse SessionStart metadata, lazy-load project memory, and bound startup task output to five rows
  • harness-split identity contract (review fix): Claude recovers the hook-derived token via the ONEBRAIN_HOOK_SESSION_ID layer using the resolve-only session token --json verb mid-session (leaves the Stop-hook cadence counter untouched; startup fallback keeps session init), Gemini and Codex never mint one, and every checkpoint reset passes --session-token {session_token} via the preserved executable
  • wrap all three harnesses' onebrain hook commands in a shell-level || echo fail-open fallback (Claude's check-cli-version.sh gate stays the user-facing message), pinned by missing-CLI and old-CLI rollback smokes in check-lifecycle-hooks.py

Verification

  • python3 scripts/check-config.py
  • python3 scripts/check-links.py
  • python3 scripts/check-skill-count.py
  • python3 scripts/check-lifecycle-hooks.py (manifest byte-exactness + lifecycle smoke + the two rollback smokes)
  • real cache-deletion smoke with the CLI worktree binary

Dependency and rollout

Depends on onebrain-ai/onebrain-cli#396.

Release CLI v3.4.25 through supported installation channels before merging or releasing plugin v3.4.12. Rolling the CLI back below 3.4.25 degrades Codex/Gemini lifecycle hooks to an inert SessionStart warning (the shell fallback, verified by the rollback smokes), while Claude blocks at session start via check-cli-version.sh — restore CLI >= 3.4.25 to re-enable.

kengio added 13 commits August 26, 2026 16:26
…-scoped checkpoint reset

The SessionStart-injected identity contract had over-generalized Codex's
terminal-fallback danger onto Claude/Gemini, disabling their legitimate
session init fallback (their tokens derive from harness env like
CLAUDE_CODE_SESSION_ID and are chat-unique). Split every fallback/disable
rule in INSTRUCTIONS.md by harness: Claude/Gemini recover via
`session init --json` and treat the result as authoritative; Codex keeps
checkpoint/wrapup disabled and never mints a replacement token.

Also align skill docs with the companion CLI's new
`checkpoint reset --session-token <TOKEN>` flag, and apply the same
harness split wherever a skill told the agent to recover identity via
session init.
Codex and Gemini hook manifests called bare `onebrain hook` with no
version gate. A CLI older than 3.4.25 has no `hook` subcommand, so it
exits 2 (clap usage error) — the blocking exit code in the hook
protocol — contradicting the "every hook is fail-open" and "rollback
disables these hooks" claims. Claude is protected by its
check-cli-version.sh SessionStart gate; Codex and Gemini had neither a
gate nor a fallback.

Wrap each command in a shell-level `|| echo` fallback: SessionStart
echoes a warning additionalContext when `onebrain hook` fails,
PostToolUse/Stop echo `{}`. Update check-lifecycle-hooks.py to assert
the exact wrapped strings and add rollback smoke cases (missing CLI,
CLI without the hook subcommand) pinning that the fallback returns
exit 0 with the expected stdout.
…r; Gemini joins the no-mint rule; wrap Claude hooks

Round-2 review findings:
- Claude's session-identity fallback now re-runs `session init --json` with
  ONEBRAIN_HOOK_SESSION_ID set to CLAUDE_CODE_SESSION_ID, so the recovered
  session_token is provably the same sha256[..16] token the Stop hook
  increments (empirically verified against the CLI resolver). Gemini moves
  into the same no-mint bucket as Codex: its resolver has no harness-session
  env layer, so a terminal/process/day-scoped fallback token could merge
  chats.
- hooks.json's Claude SessionStart generic hook is now wrapped in the same
  `onebrain hook || echo '{}'` fail-open fallback Codex and Gemini already
  use, so a pre-3.4.25 or missing CLI degrades gracefully instead of exiting
  2 (Claude's check-cli-version.sh gate remains the messaging layer).
  check-lifecycle-hooks.py updated in lockstep, its Gemini commandWindows
  absence now asserted explicitly, and the Windows-string limitation is
  documented near the commandWindows constants.
- Stale "bare onebrain hook" / "no wrapper needed" prose in GEMINI.md and
  CONTRIBUTING.md corrected to describe the fail-open wrapper.
- Skills now spell the preserved `{resolved executable}` placeholder instead
  of bare `onebrain` for session init / checkpoint reset recovery commands,
  and the stale `SESSION_TOKEN` key reference is corrected to `session_token`.

CHANGELOG.md's existing v3.4.12 bullets updated in place (same count) to
match.
… scope wrapper claims accurately

Round-3 audit fixes:
- Mid-session Claude token recovery (INSTRUCTIONS.md Auto Checkpoint section,
  pause/wrapup/AUTO-SUMMARY SKILL.md, session-formats.md) now calls the
  resolve-only `session token --json` instead of `session init --json`.
  `session init` deletes the Stop-hook cadence state file whenever it runs
  mid-session, so recovery must not use it; Step 1's startup fallback keeps
  `session init` on purpose since a fresh session needs that state-clean
  side effect and the full startup metadata.
- Corrected the inverted fail-open description: the `|| echo` wrapper is
  inert once the installed CLI is 3.4.25+, and degrades to a harmless
  stand-in payload when the CLI is missing or older (INSTRUCTIONS.md).
- Rescoped "all three harnesses wrapped" claims (CHANGELOG.md, CONTRIBUTING.md,
  INSTRUCTIONS.md): only Codex's and Gemini's entries plus Claude's
  SessionStart are plugin-shipped and wrapped in `|| echo`. Claude's
  PostToolUse/Stop entries are CLI-registered into the vault's
  .claude/settings.json in exec form and can't carry a shell `||`; those
  are covered by the check-cli-version.sh SessionStart gate instead.
- Dropped stale "bare" wording in migration-steps.md's /update hook
  registration step, mirroring the corrected CONTRIBUTING.md phrasing.
- Quoted the `{resolved executable}` placeholder in every recovery/reset
  one-liner (POSIX and PowerShell forms) so paths with spaces don't break.
@kengio
kengio merged commit 56b3755 into main Aug 28, 2026
4 checks passed
@kengio
kengio deleted the fix/codex-hook-cache-lifecycle branch August 28, 2026 03:04
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