Conversation
The third documented refresh trigger (alongside the every-5-prompts counter and the >10-min gap) was deferred in CLAUDE.md as an open question. Claude Code's hook system actually exposes `PostCompact` with a JSON payload — feasibility is no longer a question. Wire-up: - New `cmd_mark_compact` writes `.claude/revive-compact.signal` with a unix timestamp. Like `cmd_refresh`, it is on the hook hot path: always exits 0, fails silently, mkdir best-effort. - `cadence_gate` checks for the signal first. If present, it removes the signal, logs `post-compact: forcing emit`, and emits regardless of counter or time-gap. The counter still ticks so subsequent calls resume normal cadence. - `cmd_install_hook` now also wires `PostCompact` → `revive mark-compact` alongside the existing `UserPromptSubmit` → `revive refresh` entry. Refactored the upsert into a small inner helper so both events go through the same idempotency check. Why post-compact specifically: agents lose most of their context when the user runs `/compact` (or AutoCompact fires). That is precisely when re-injecting a brief produces the highest ROI — waiting for the next 5-prompt boundary throws that opportunity away. 8 new tests cover signal lifecycle (write, consume, counter advance), the silent-failure contract, install-hook idempotence for both hooks, and the help-text surface. 125 / 125 pass; shellcheck clean.
There was a problem hiding this comment.
Pull request overview
Adds a new “post-compact” refresh trigger to revive so that immediately after a Claude Code /compact (or AutoCompact), the next revive refresh bypasses cadence and emits the brief.
Changes:
- Introduces a
mark-compactsubcommand that writes a.claude/revive-compact.signalfile. - Updates
cadence_gateto detect/consume the signal and force an immediate emit. - Extends
install-hookto wire bothUserPromptSubmitandPostCompact, plus adds Bats coverage for the new behavior.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
bin/revive |
Adds compact signal + mark-compact, forces cadence override when signal exists, and installs the new PostCompact hook. |
tests/revive.bats |
Adds tests for signal lifecycle, forced refresh behavior, and install-hook idempotency across both hook events. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codex flagged that doctor only validates `UserPromptSubmit`, so an upgraded install that hasn't re-run `install-hook` would silently miss the new `PostCompact` wire-up — `/compact` refresh would never fire and doctor would still say "all checks passed". Refactored the hook-check into an inner helper `_doctor_check_hook` that takes (event, command-pattern). Calls it twice — once for UserPromptSubmit/refresh, once for PostCompact/mark-compact. Same jq-then-grep fallback semantics as before. New test "doctor warns when only UserPromptSubmit is wired (upgrade gap)" reproduces the exact scenario codex called out: hand-craft a settings.json with just the legacy hook, confirm doctor surfaces the missing PostCompact entry.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| chmod -w . | ||
| run "$REVIVE" mark-compact | ||
| chmod +w . |
There was a problem hiding this comment.
This test relies on chmod -w . to make the directory unwritable, but it doesn’t assert that the chmod calls succeeded. If chmod fails (platform/FS quirks), the test can pass while not actually exercising the silent-failure path. Add || return 1 (or equivalent) after the permission changes (and ideally ensure permissions are restored via a trap) to avoid false positives.
| chmod -w . | |
| run "$REVIVE" mark-compact | |
| chmod +w . | |
| trap 'chmod +w . || true' RETURN | |
| chmod -w . || return 1 | |
| run "$REVIVE" mark-compact |
The silent-failure test could pass without exercising the silent-failure path if `chmod -w .` itself failed (e.g., FS quirk on CI). Add `|| return 1` so the test fails fast, and a RETURN trap so the write permission is restored even if a later assertion bails — otherwise a leaked read-only WORKDIR breaks teardown.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
* docs(readme): document the post-compact refresh trigger Cadence section now lists four triggers (was three): first prompt, every-N counter, time-gap, and the new post-compact override. Quick start mentions install-hook now wires both UserPromptSubmit and PostCompact. * feat: refresh trigger after `/clear` Sibling to the post-compact trigger from #30. `/clear` wipes more than `/compact` (full conversation reset), but the recovery path is identical — re-inject the brief on the next prompt, bypassing cadence. Wired through Claude Code's `SessionStart` hook with `matcher: "clear"`, the documented dedicated signal. Implementation: - New `cmd_mark_clear` writes the same `.claude/revive-compact.signal` as `cmd_mark_compact`. Two commands so settings.json reads naturally and hook.log distinguishes the source. - `cmd_install_hook` now wires three hooks. Refactored the upsert helper to take an optional `matcher`, so SessionStart{clear} stays distinct from any user-added SessionStart{startup} or {resume} entry (idempotency key: event + matcher + command). - `cmd_doctor` adds a third hook check via the existing `_doctor_check_hook` helper (`SessionStart` + `revive mark-clear`). - README cadence section gains trigger #5; install-hook line now lists all three events. 6 new tests cover: signal write, help-text surface, settings.json shape (matcher field present), 3-hook idempotency, doctor warn on missing SessionStart, doctor green path with all three hooks. * release: v0.2.0 Headline: context-loss recovery. Refresh now fires immediately after `/compact` (#30) and `/clear` — the two moments when an agent has just lost most of its working memory and the brief gives the highest ROI. Three hook events wired by `install-hook`: UserPromptSubmit, PostCompact, SessionStart(matcher=clear). Also since v0.1.19: - `revive init` auto-fixes `.gitignore` so static.md is trackable (#31) - README tagline rewrite (#31) * fix(doctor): validate SessionStart matcher (codex P3) `_doctor_check_hook` accepted any SessionStart entry pointing at `revive mark-clear` regardless of its `matcher` value. A user who hand-wired SessionStart{startup} → mark-clear (or no matcher at all) would pass doctor, but `/clear` would never trigger that hook. Codex flagged the false-positive on the v0.2.0 PR. Two changes: 1. The helper takes an optional 3rd arg `matcher`. When set, the jq query also asserts `(.matcher // "") == $m` so only the intended entry counts. Doctor labels include the matcher in parens — `SessionStart(clear) hook installed`. 2. The grep fallback used to override a legitimate "no match" from jq because it ran on any non-zero jq exit. Distinguish jq's exit codes: - 0 → match; - 1 → legitimate no-match (trust it, skip grep); - ≥2 → jq error or absent → grep fallback (best-effort, can't tie matcher to command across JSON lines). Without that, the matcher check would have been silently defeated whenever jq returned 1 and grep happened to find the command string anywhere in the file. Also: `set -e` interaction. The naive `jq ...; rc=$?` pattern would abort the function on jq's non-zero exit before the assignment. Wrapping in `if jq ...; then rc=0; else rc=$?; fi` preserves the code. Tests: - "doctor warns when SessionStart entry has wrong matcher" — new regression test for codex P3, hand-crafts settings.json with matcher=startup pointing at mark-clear, asserts the warning. - Existing missing-SessionStart and all-three-hooks tests updated to expect the `(clear)` label.
Summary
Adds the third refresh trigger that was previously deferred as an open question in
CLAUDE.md: fire immediately after a/compact(or AutoCompact) event.Wire-up:
cmd_mark_compact— new PostCompact hook entry point. Writes.claude/revive-compact.signal(timestamp), exits 0 silently, mkdir best-effort. Same silent-failure contract ascmd_refresh.cadence_gate— now checks for the signal first. If present, deletes it, logspost-compact: forcing emit, emits regardless of counter / time-gap. Counter still ticks so subsequent calls resume normal cadence.cmd_install_hook— now wires bothUserPromptSubmit → revive refreshANDPostCompact → revive mark-compact. Refactored upsert into an inner helper so idempotency works for both.Why post-compact specifically
Agents lose most of their context after
/compact. That is exactly when re-injecting the brief gives the highest ROI — waiting for the next 5-prompt boundary throws that window away. Confirmed feasibility viaclaude-code-guide:PostCompactis a documented hook event withmanual/automatchers.Test plan
bats tests/— 125/125 passshellcheck bin/revive install.shcleanrevive mark-compactwrites signal →revive refreshemits brief and removes signalrevive doctorstill all-greenMigration
Existing users:
revive install-hookis idempotent — re-running it adds thePostCompactentry next to the existingUserPromptSubmitentry without duplication.🤖 Generated with Claude Code