Skip to content

justi/context-revive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

context-revive

Your agent forgot the ADR you wrote 30 prompts ago.

A bash CLI that re-injects your curated project brief into Claude Code on a cadence — fights context rot before AutoCompact summarizes your decisions away.

Example — when your agent forgets what you told it

30 prompts in. AutoCompact fires. Background jobs feel slow, so you ask the agent: "can we add Redis + Sidekiq for the queue?" It says yes — forgetting you spent an entire ADR deciding Postgres-backed jobs only, no new infrastructure.

With revive, the PostCompact hook just refreshed your project's .revive/static.md into the recent attention window:

PURPOSE: Internal billing service for a 12-person team. Goal: ship
features without growing the on-call surface — the team has no DevOps.
Constraint: Postgres is the only datastore; no Redis, no Kafka, no
new infra without exec sign-off.
INVARIANTS:
  - Background jobs run on solid_queue (Postgres-backed). No Sidekiq,
    no Redis queues. Decided in ADR-014.

So the agent pushes back: "Sidekiq + Redis violates ADR-014 and the no-new-infra constraint. Want to revisit the ADR, or solve queue latency another way — raise solid_queue concurrency, partition the jobs table?"

The decision you made 30 prompts ago is still load-bearing.

Install

curl -fsSL https://raw.githubusercontent.com/justi/context-revive/main/install.sh | bash

Requires bash + git. Optional: jq (for install-hook), gh (for best-quality PURPOSE auto-detection).

Do I need this?

Use this if you keep hitting the same failure in Claude Code: 30 prompts in, the agent forgets an ADR, re-suggests an approach you already rejected, or asks questions CLAUDE.md already answered. You probably don't need it if your sessions are short (<15 prompts), CLAUDE.md stays under 1k tokens, or you already restart sessions frequently.

Not a replacement for CLAUDE.md, Cursor Rules, or AGENTS.md — those load once at session start and get summarized away by AutoCompact. This keeps your curated facts fresh in the recent attention window, complementary to them.

One bash script, zero runtime on the hot path. Works with any agent via paste (revive show | pbcopy); Claude Code gets first-class hook integration.

Quick start

cd your-project
revive init              # scaffold .revive/static.md; PURPOSE auto-detected, 3 sections left as placeholders
revive suggest | pbcopy  # paste into active agent — agent rewrites PURPOSE/DIFFERENTIATORS/INVARIANTS/GOTCHAS
revive audit   | pbcopy  # paste into a FRESH session — agent proposes bullets the first pass missed
revive install-hook      # wire UserPromptSubmit + PostCompact + SessionStart(clear) into .claude/settings.json
revive doctor            # sanity-check the install (git, static.md, hook, log)
revive show              # preview the assembled brief (forced emit, ignores cadence)

The two-pass flow (suggest then audit in a fresh session) is deliberate: a single session that both generates and audits its own output suffers from context saturation and self-critique sycophancy. Fresh context finds gaps the generation pass can't. suggest rewrites placeholder sections; audit only APPENDS bullets to existing sections after your approval.

Most useful next

Everything below is optional — the quick start gives you a working hook.

Reference

What .revive/static.md looks like

Four flat sections. Immediately after revive init, the file has PURPOSE filled (auto-detected — see the chain in Design notes) and three placeholder sections waiting for your edits:

PURPOSE: <auto-detected from gh / manifest / CLAUDE.md / README>
DIFFERENTIATORS:
  - (what sets this project apart; edit this file)
INVARIANTS:
  - (top-5 architectural rules; edit this file)
GOTCHAS:
  - (landmines you keep stepping on; edit this file)

PURPOSE is one physical line in the file — no \n in the middle, even when it holds 2–3 sentences and wraps visually in your editor (up to 400 characters). The three other sections are bullet lists under a section header.

After revive suggest + revive audit (or a hand edit), the file looks like:

PURPOSE: Background-job scheduler for small Go services. Success metric is zero surprise job failures after a deploy — goal: replace ops-managed cron with code-defined schedules that survive rollouts. Constraint: job state lives in the app's own Postgres; no new infrastructure.
DIFFERENTIATORS:
  - Traditional cron → schedules defined in code, survive deploys
  - Managed SaaS schedulers → zero new infrastructure; reuses app Postgres
  - Temporal / DAG workflow engines → single-step jobs only; keep it small
INVARIANTS:
  - Every schedule change ships with a migration; never edit rows in prod.
  - Jobs must be idempotent — retries on deploy-overlap are expected.
  - Worker binary must not grow past 30 MB (embedded-device deploy target).
GOTCHAS:
  - `make test` runs integration against a real Postgres — set TEST_DATABASE_URL.
  - `bin/deploy` always runs `schedule:apply` last; reordering breaks overlap detection.

The file is checked in. revive show assembles the brief around it on each refresh. Placeholder-only sections (still saying "(edit this file)") are suppressed from the emitted brief — no noise injected to the agent.

How often the brief is injected

Emits when ANY of these is true:

  1. First prompt of the session (counter = 1).
  2. Every 5th prompt after that, via REVIVE_REFRESH_EVERY (default 5).
  3. Gap of >10 minutes since the last emit, via REVIVE_REFRESH_TIME_GAP (default 600 seconds).
  4. Right after /compact (or AutoCompact). The PostCompact hook drops .claude/revive-compact.signal and the next refresh consumes it, bypassing cadence — that's the moment the agent has lost the most context, so re-injecting the brief gives the highest ROI.
  5. Right after /clear. SessionStart with matcher: "clear" drops the same signal — /clear wipes more than /compact, same recovery path applies.

Prompts between emits see nothing from revive — silent skip, zero cost. Tune in your shell:

export REVIVE_REFRESH_EVERY=3        # every 3rd prompt
export REVIVE_REFRESH_TIME_GAP=300   # 5-minute gap threshold

Token cost in practice

Measured on a rich-architecture project (Python + Streamlit + 19 ADRs, .revive/static.md ≈ 4 KB with 12 INVARIANTS, 8 GOTCHAS):

Scope Tokens % of Opus 4.7 1M
Brief per emit ~2–3k ~0.25%
30-prompt session (6 emits) ~15k ~1.5%
Claude Code hook hard cap 10k chars per emit

English-only repos land closer to ~1.5k per emit; Polish/mixed with unicode glyphs runs higher. Measure your own by running /context before and after a prompt that triggers the hook — the delta in Messages is the emit cost.

Reset / regenerate from scratch

If .revive/static.md drifted (old extractor, stale rules, marketing-tagline PURPOSE slipped in):

cd your-project
rm -rf .revive
revive init
revive suggest | pbcopy          # paste → agent rewrites the file end-to-end
revive audit   | pbcopy          # paste into FRESH session → agent fills gaps
revive show                      # verify

Lighter alternative: revive init --force regenerates only PURPOSE and preserves user-edited DIFFERENTIATORS / INVARIANTS / GOTCHAS.

Upgrade to a new version

curl -fsSL https://raw.githubusercontent.com/justi/context-revive/main/install.sh | bash
revive version
revive doctor                    # sanity-check the install

Re-writes ~/.local/bin/revive. Per-project .revive/static.md files and Claude Code hook settings are not touched. Release notes flag when a version adds a new section and you may want revive init --force to regenerate scaffolding.

Design notes

What goes in (evidence-backed non-inferable facts)

  • PURPOSE — one physical line, ≤400 chars, typically 2–3 sentences covering what the project is, its business goal, and the one hard constraint that shapes design decisions. Auto-detected via a chain: gh repo view --json description → manifest description (pyproject, package.json, Cargo, gemspec, composer) → CLAUDE.md first paragraph → filtered README prose. First hit wins.
  • DIFFERENTIATORS, INVARIANTS, GOTCHAS — human-curated (via suggest + audit, user-reviewed). Research: "Human curation yields ~4% performance gains; auto-generation reduces success rates by 0.5–2%" (Augment Code, 2026).
  • STATEgit branch + last 3 commits (subject only for subject-only commits; subject plus the first paragraph of the body, truncated to ~100 chars, for commits that carry a body). Squash-merge bodies typically hold the PR description, so this surfaces PR context for free without a gh API call.
  • HOT_FILES — top 5 files by commit-frequency over the last 20 commits, each annotated with the last commit subject.
  • COMMANDS — exact test / lint / build / dev / setup invocations. Source priority: .revive/commands.md override → Rails bin/* (if Gemfile or *.gemspec present) → package.json scriptsMakefile targets → Rails bin/* fallback. Whole section is suppressed if no source matches.

What we deliberately don't inject

Auto-generated architecture overview, directory tree, dependency graph, full file contents, LLM-summarized anything on the hot path. Evidence: "Directory trees cause stale structural references that mislead agents", and auto-generated summaries reduce agent success rate by 0.5–2% while increasing cost 20%+ (Augment Code, 2026). If you want an architecture summary in the brief, write it by hand into INVARIANTS.

Complementary to AutoCompact

Anthropic's AutoCompact fires at the context-window ceiling — it summarises the conversation to make room. revive addresses a different failure: context rot, where the agent forgets as tokens drift out of attention long before AutoCompact triggers. Cadence-based re-injection keeps key facts in the recent window (Zylos, 2026 splits context into stable prefix + fresh suffix — our STATIC/DYNAMIC split maps cleanly).

Why a shell script?

Zero runtime. <100ms cold start. Transparent — cat $(which revive). One file to audit, no dependency tree. The point of this repo is that it works on any dev machine without installing a language toolchain.

Status

Pre-alpha. Weekend MVP in active dogfooding. v0.2.0 — context-loss recovery: refresh fires after /compact and /clear; revive init auto-fixes .gitignore; sharper tagline; see Releases for history.

License

MIT

About

Your side project died at 80%. Bring it back in one prompt. Shell-script CLI that re-injects dense, deterministic project briefs into Claude Code via the UserPromptSubmit hook.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages