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 between Live, Pulse, and Stream without losing the active ref, the selected commit, or any filters. Each lens is a different way to read the same observed facts.
The commit timeline as a single, calm column.
The default view. Refs, working-tree changes, and incoming commits read top to bottom. Live updates do not steal focus and do not auto-scroll the row you were reading.
A canvas of file-change particles, drifting and bursting in real time.
Each particle is a file, colored by its kind and sized by how often it changes. When a file's contents shift, that particle bursts with sparks and a brief flash. Idle, the field breathes; busy, it pops like popcorn. Right-click any particle to open its file history; uncommitted edits surface alongside committed changes.
One row per file change, in reverse chronological order.
An event-shaped feed: status, path, additions, deletions, and the commit it belongs to. New commits arrive at the top; working-tree edits are interleaved as they happen. Right-click a row to open its file history.
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.
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 readingMulti-repository view with several observatories visible at once instead of one at a timeReflog 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.