History rewrites, recorded as facts
When a force push, rebase, or reset moves a ref, Refscope captures the previous tip, the new tip, the time, and the source of detection. The recoverable hash stays visible so the work is never described as lost.
An observatory for your refs.
Refscope is a local, read-only observatory for Git refs and history. It watches one repository at a time, records what changes, and separates what was observed from what it means.
What you get
When a force push, rebase, or reset moves a ref, Refscope captures the previous tip, the new tip, the time, and the source of detection. The recoverable hash stays visible so the work is never described as lost.
What was observed (ref, hash, timestamp) is shown in one column. What it means (rewritten, merge, signature unknown) is shown in another. You can paste the facts into a postmortem without copying anyone's opinion.
Live updates do not steal focus, do not auto-scroll, and pause on demand. Status is conveyed by colour, shape, and text together — the page survives greyscale printing, screen readers, and reduced motion.
Lenses
Switch perspectives without losing the active ref, the selected commit, or any filters. Each lens is a different way to read the same observed facts.
Timeline
The default lenses. Each reads the same commits and working-tree edits in a different shape.
The commit timeline as a single, calm column. Live updates do not steal focus and do not auto-scroll the row you were reading.
A canvas of file-change particles, colored by kind, sized by churn, bursting when a file changes. Idle, it breathes; busy, it pops.
One row per file change, in reverse chronological order. New commits arrive at the top; working-tree edits are interleaved as they happen.
Risk
Aggregate views over churn, drift, and rewrite-adjacent state. Read them like an observation log, not an alarm bell.
LOC against churn on a scatter, with a ranking table beside it. Surfaces files where refactoring would pay back.
Per-commit `riskScore` as an area chart over time, with brush-to-zoom and a click-through to the commit detail.
Author × date or date × hour intensity. Cells encode score with a colour-blind safe scale tied to dynamic thresholds.
A force-directed graph of files that move together. Edge weight is the co-change count; double-click opens file history.
All local branches on an ahead/behind scatter. Point size encodes staleness; quadrants label Aligned, Hot, Stale, Diverged.
Three columns of work that has not left your machine yet: uncommitted, stashed, and ahead of upstream.
Specialist
Lenses that open in specific situations — a rewrite to recover from, a window to summarise, a symbol to follow.
Activity over 24h or 7d as a 2×2 dashboard: top contributors, hotspot delta, risky commits, and ref activity.
Every observed history-rewritten snapshot with copyable `git reflog` and recovery-branch commands. Refscope never runs them for you.
A single symbol's history across commits, opened from a file row. Useful when one function or class is the thread you are pulling.
Demo
The sidebar shows the ref name, the previous tip, the current tip, and the observed time. Nothing flashes. The recoverable hash stays visible so the user can run git reflog to recover.
Each commit is one row: hash, author, message, additions and deletions, signature status. New commits arrive without scrolling the row you were reading.
Pick a base ref and a target ref. Refscope returns ahead and behind counts, file totals, and three copyable Git commands — log, diff --stat, diff — with the revisions kept as separate tokens.
Press pause. New observations are counted in the badge but the timeline holds still. Resume to apply the queue. Useful when you are reading a commit and a teammate force-pushes.
Cmd or Ctrl plus K. Run pause, copy current commit hash, clear path filter, and the page state updates in place. The palette does not maintain a parallel list of refs or commits.
Hash, parents, refs, change graph, file-status mix, and the changed-files list sit in a column of their own. Interpretation lives in badges next to the facts, never inside them — paste the hash without copying anyone's opinion.
Aggregate observations over a window into labelled bars — commit count, additions, deletions, signed commits, merge commits, and live-update arrivals — read like a telescope's nightly log.
Switch the status palette to the Wong scheme so red, orange, blue, and yellow stay distinguishable for protan, deutan, and tritan vision. Status text and shapes carry the same meaning in either palette.
Switch from Live to Pulse. Each particle is a file, colored by its kind and sized by how often it changes. When a file shifts, that particle bursts with sparks and a brief flash; idle, the field breathes. Uncommitted edits drift in the same field alongside committed changes.
Switch to Stream. Each row is a single file change — status, path, additions, deletions, and the commit it belongs to — in reverse chronological order. New commits arrive at the top; working-tree edits are interleaved as they happen.
Right-click any file row, or open the path prompt from the top bar, to see one file's history: a hunk timeline, a branch-drift halo, and a related-files panel that surfaces co-change neighbours from the same commits.
Switch to Hotspot. Each file is a point: X is lines of code (log scale), Y is churn, size is recency of the last change. A ranking table sits beside the scatter; clicking a row or a point opens that file's history in place.
Switch to Risk Trend. The area chart reads riskScore for each observed commit; horizontal lines mark the LOW and HIGH thresholds; the brush lets you zoom the window. Click a point to open that commit in the detail panel.
Append ?fleet=1 to switch into Fleet mode. Refscope polls every allowlisted repository every 30 seconds, aggregates activity over a 1h, 6h, 24h, or 7d window, and lists per-repo SSE availability. Click a row to drop into that repository in Detail mode.
Why an observatory?
Git history is rewritten in places no one is watching. A force push, a reset, a reflog expiry — yesterday's commit becomes today's stranger, and the only record of the change is the change itself.
Refscope is the observatory. It opens beside your repository, records what was observed, and separates that record from any interpretation. It does not raise alarms. It does not infer intent. It writes down the time, the ref, and both hashes, the way a telescope log writes down the time, the coordinates, and the seeing conditions.
When the question comes — "what happened to main at 02:17?" — Refscope has an
answer that does not require trust in Refscope. The evidence is there, in the same form a
Git command would have produced, with the interpretation labelled separately so it can be
agreed with or rejected on its own.
Security and sandbox
The constraints below are enforced in code, not in documentation.
| What | How |
|---|---|
| Repository access | Allowlist via RTGV_REPOS. Only listed repository ids are served. |
| Git commands | A fixed read-only set: cat-file, diff, for-each-ref, log, merge-base, rev-list, rev-parse, show. |
| Spawn model | Argument-array, shell: false, --no-pager, bounded stdout and stderr, timeouts. |
| Environment | GIT_*, SSH agent, proxies, GCM, lazy fetch, terminal prompt, optional locks, ext-diff, and textconv are stripped or disabled. |
| Cryptographic signatures | Not verified. Refscope reports signed: false and signatureStatus: "unknown" rather than guess. |
| Network surface | Localhost HTTP. Default origins: 127.0.0.1:5173, localhost:5173. Override with RTGV_ALLOWED_ORIGINS. |
Quickstart
Run Refscope against this directory
npx -y github:simota/refscope Open the observatory
http://127.0.0.1:4175 The CLI opens this URL automatically. The address is here for reference.
To watch a different repository, pass an absolute path: npx -y github:simota/refscope --repo /absolute/path/to/git/repo.
To skip the auto-open, add --no-open.
Refscope rejects non-Git roots before serving.
Building from source (make dev-self) is documented in the repository readme.
Beyond MVP
Refscope is a v0. Below is what is honest to say about what comes next, and what does not.
Likely nextStatic export of the recorded observation log for offline readingReflog overlay so recoverable hashes stay reachable from the timeline after a rewriteNot in scopeCryptographic signature verification (would invoke external GPG)Operations against the repository (no commit, no push, no rebase)Cloud or remote agent (local-first only)No quarter-by-quarter dates. No Q3-2026 promises. The repository's open issues are the source of truth.