fix(codex): restore Superpowers after compaction

Codex re-fires SessionStart with source "compact" after every context
compaction; the summary keeps progress but sheds the bootstrap and any
active skill's instructions — measured July cause of post-compaction
dispatch drift in long SDD runs (with re-injection: 18/18 hook fires,
66/66 post-compaction dispatch tuples correct in a 12.4h stress run).
Codex discovers skills natively at startup, so the hook is silent
there: the compact re-fire is the one unowned lifecycle point.

Adds the plugin-provided hook (hooks-codex.json + session-start-codex,
compact-only, fails open), wires it into the manifest and package,
documents install/trust behavior, updates codex-tools.md with the
re-grounding fallback, and tests the hook lifecycle, manifest, and
archive contents.

Rebuilt from the July codex-spinout-fixes branch, pared to the hook
core: the dispatch-hints layer it used to ride with is superseded by
the merged 2059-2062/2077-2080 stack and is dropped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Drew Ritter
2026-08-04 14:55:28 -07:00
parent 05c2393b82
commit 36f3883f4e
10 changed files with 264 additions and 23 deletions

View File

@@ -40,8 +40,9 @@ Options:
-h, --help Show this help.
The archive is rootless: .codex-plugin/, assets/, skills/, README.md, LICENSE,
and CODE_OF_CONDUCT.md sit at the archive root. Source-only repo files, hooks, tests,
docs, and other harness manifests are intentionally not shipped.
CODE_OF_CONDUCT.md, and the Codex SessionStart hook (hooks/hooks-codex.json plus
its two scripts) sit at the archive root. Source-only repo files, other-harness
hooks, tests, docs, and other harness manifests are intentionally not shipped.
EOF
}
@@ -238,6 +239,9 @@ git -C "$REPO_ROOT" -c tar.umask=0022 archive --format=tar "$REF" -- \
LICENSE \
README.md \
assets \
hooks/hooks-codex.json \
hooks/run-hook.cmd \
hooks/session-start-codex \
skills \
| tar -xpf - -C "$STAGE"
@@ -333,7 +337,7 @@ esac
unexpected_paths="$(
printf '%s\n' "$archive_paths" |
grep -E '(^superpowers/|^\.agents/|^hooks/|package\.json$|^\.git|^\.pytest_cache|^\.ruff_cache|^scripts/|^tests/|^docs/|^evals/|^lib/|^\.claude|^\.cursor|^\.kimi|^\.opencode|^\.pi|^AGENTS\.md$|^CLAUDE\.md$|^GEMINI\.md$|^RELEASE-NOTES\.md$|^CHANGELOG\.md$)' || true
grep -E '(^superpowers/|^\.agents/|^hooks/hooks\.json$|^hooks/hooks-cursor\.json$|^hooks/session-start$|package\.json$|^\.git|^\.pytest_cache|^\.ruff_cache|^scripts/|^tests/|^docs/|^evals/|^lib/|^\.claude|^\.cursor|^\.kimi|^\.opencode|^\.pi|^AGENTS\.md$|^CLAUDE\.md$|^GEMINI\.md$|^RELEASE-NOTES\.md$|^CHANGELOG\.md$)' || true
)"
if [[ -n "$unexpected_paths" ]]; then
printf '%s\n' "$unexpected_paths" | sed 's/^/ /' >&2