drift-report
Skill4 starsChanged 5 months agoMITView on GitHub
Use to check the shared library, the current wiki, and all registered projects for accumulated drift — un-indexed PDFs, scans without a text layer, PDF bloat, project-bib keywords not yet merged into the master, cross-project bibkey collisions, lint regressions from out-of-band edits. Wraps hooks/drift_check.py, the same state-triggered check that runs automatically at session start. Triggers on "drift report", "check everything", "was steht an", "prüf mal alles", "ist alles konsistent", "check the library". NOT wiki-lint (single-project structural lint — this composes it), NOT semantic-wiki-review (LLM content audit — this is deterministic only).
1 other project uses a version of this.
Adopted by
Most recently taken up by
- Leostruka/devin-bundletheir own version, first seen Nov 1, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- Leostruka/devin-bundle★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository16 other files it gives its agents.
- acquire-sourcesSkill
- add-to-librarySkill
- brainstorming-researchSkill
- drafting-manuscriptSkill
- executing-research-planSkill
- finishing-a-research-projectSkill
- grant-finderSkill
- ingest-sourceSkill
- literature-reviewSkill
- requesting-peer-reviewSkill
- scaffold-research-projectSkill
- semantic-wiki-reviewSkill
- using-research-powersSkill
- wiki-graphSkill
- wiki-lintSkill
- writing-research-planSkill
The file
Files
Drift Report
Deterministic maintenance findings across three scopes — current project, shared library, all registered projects — produced by the same script the SessionStart hook runs. Report-only with one exception: the incremental search-index update (a derived cache).
Announce at start: "Using drift-report to check for accumulated drift."
How the automatic path works (so you can explain it)
At session start, hooks/drift_check.py compares cheap fingerprints (library
PDF count/mtimes, master-bib hash, each registered project's bib hash, the
current wiki's file count/mtimes) against ~/.cache/research-superpowers/drift-state.json.
Nothing changed → nothing runs, nothing is injected. Drift is caused by
actions, not by time — in-session actions are covered by the skills that cause
them (ingest lints, add-to-library re-indexes); the hook covers what happens
out-of-band: manual VPN downloads, Nextcloud syncs from teammates, Obsidian
edits, ingests in other projects. The first run is a silent baseline.
Kill switch: RESEARCH_SUPERPOWERS_NO_DRIFT_CHECK=1.
Manual run (this skill's job)
python3 "$CLAUDE_PLUGIN_ROOT/hooks/drift_check.py" --force --human--force ignores the fingerprints (checks everything now — this is how you
inspect a freshly installed machine despite the silent baseline); --human
prints the report instead of hook JSON. Run from a project root when possible —
the wiki-lint scope only exists there.
The checks, and what each finding means
| Finding | Meaning | Fix (never run without the user's go-ahead) |
| lint FAILS after out-of-band edit | someone edited knowledge/ outside a session (Obsidian, editor) | python scripts/lint-wiki.py, then fix per wiki-lint skill |
| PDFs with no text layer | scans arrived (VPN download, teammate sync) — invisible to search | ocrmypdf, then re-index |
| PDFs unreadable | corrupt files in the library | bib-search.py status for the list |
| PDFs > 40 MB | publisher bloat syncing to everyone, forever | optimize-pdf.py scan . → optimize after review |
| merge drift | ingests wrote bibkeys/keywords into project bibs that the master lacks — new keywords are invisible to every OTHER project's bib-search until merged | merge-bibs.py --report-only first, review FACTUAL conflicts, then merge |
| bibkey COLLISION / SPLIT | one key names two works (a false cross-project join) or one work has two keys (a silently missed join) | migrate-citekeys.py, guided by the audit output |
| project sync drift | a project's copied schema/ + scripts/ come from an older plugin version — its linter validates against rules the plugin has since changed, and the error reads like a wiki problem | sync-project.py --from-registry to see it, --apply to fix |
| index updated (info) | the one permitted mutation — derived cache, incremental | nothing to do |
Three of these tools live in the plugin, not in the project. merge-bibs.py,
migrate-citekeys.py and sync-project.py are maintainer tools operating across projects, so they are
not mirrored into the template — python scripts/merge-bibs.py from a project root
fails with "No such file or directory". Run them from the plugin:
python3 "$CLAUDE_PLUGIN_ROOT/scripts/merge-bibs.py" …. The report's → lines
already carry the absolute path. Everything else in the table (bib-search.py,
optimize-pdf.py, lint-wiki.py) is template-mirrored and runs project-relative.
Never expand the registry in the shell. Pass --from-registry and let
merge-bibs.py read ~/.config/research-superpowers/projects itself. Both shell
forms lose projects silently, in opposite directions: --roots $ROOTS does not
word-split in zsh and arrives as one nonexistent path, while
--roots $(grep -v "^#" …) splits in bash and zsh — including inside a path, so
a project under …/Mobile Documents/… arrives as several nonexistent fragments.
A dropped project makes the report say "0 FACTUAL conflicts" about a set that never
contained it, and inflates the master-only count. --roots <p1> <p2> … stays for
explicitly named projects; quote every path.
Registry
Cross-project checks read ~/.config/research-superpowers/projects (one
project root per line, # comments). The hook auto-registers the project
each session starts in, so the registry fills itself through normal use; edit
the file to add projects you never open with Claude Code, or to remove retired
ones.
Red flags
| Thought | Reality |
| "Merge drift found — I'll just run merge-bibs with --out now" | No. --report-only first: FACTUAL conflicts (wrong DOI, wrong year) need a human verdict before anything writes to the shared master. |
| "The report is empty, so the check must be broken" | Silence IS the report. Nothing changed since the last look — verify with --force --human if in doubt. |
| "A collision — I'll rename the key in this project" | A bibkey is a cross-project join key derived from the work's metadata. Fix it with migrate-citekeys.py in EVERY affected project, not ad hoc in one. |
| "I'll OCR/optimize the PDFs right away, it's obviously needed" | Library files sync to every machine and every teammate. Surface the worklist; the user decides when the shared collection gets rewritten. |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

