Command overview
beacon git records which agent sessions produced a commit, as a git note on the commit.
Command syntax
beacon git setup installs hooks so every new commit in the repository is linked as it is made. beacon git link links one commit by hand, which is also how to link commits made before setup.
A link names a session by its harness and session id, for example beacon:claude_code/0f8e2c1a-…. The note carries identifiers only, never prompts, output, or diffs: notes can be shared with a remote, and the session’s content stays in the local runtime log. beacon handoff export <session-id> reads a linked session back.
How sessions are matched to a commit
Beacon already records every file a supported runtime writes, so matching a commit to its sessions is a read of the local runtime log. No state file is kept and nothing touches the network.- Window. Beacon reads the log from the parent commit’s time up to the commit. The window always covers at least
--min-lookback(2 hours) and never more than--max-lookback(24 hours) before the commit. Events after the commit are ignored, because they cannot have produced it. - Evidence. A session wrote a file when the log has, for that session, a
file.created,file.modifiedorfile.deletedevent, a tool event whosefile.operationis a write, a shell command whose target is plain to read (rm,mv,cp,touch,tee,sed -i,git mv, output redirection), or anapply_patchenvelope. Reads do not count. - Overlap. Beacon compares those paths with the files the commit changes, counting both sides of a rename. A session that wrote at least one of them is linked. Sessions are ordered by how many of the commit’s files they wrote, then by how recently.
git pull links nothing.
A link is an inference, not an observation. A session that edited a file a person then rewrote by hand is still linked, and a session that wrote nothing the commit kept is not.
beacon git setup
Installs Beacon’s git hooks in the current repository.
Example output
- post-commit links the new commit, exactly as
beacon git linkwould. It reads the local runtime log and writes a git note, typically in tens of milliseconds, and gives up after three seconds rather than hold a commit. It never prints, never touches the network, and never fails a commit. - post-rewrite runs after
git commit --amendandgit rebaseand tidies the note on each rewritten commit, folding the note git copied from the old commit into the one the post-commit hook just wrote. notes.rewriteRefmakes git copy a commit’s links to the commit that replaces it when you amend or rebase.
notes.rewriteRef.
A hook already in place keeps working. Beacon writes its own beacon-post-commit and beacon-post-rewrite scripts and adds a short marked block to the top of the hook that calls them, so a hook ending in exit 0 still runs Beacon’s part. Only shell hooks are edited: if the hook is another language, setup stops and prints the line to add yourself. The scripts call Beacon by the absolute path it had at setup and fall back to beacon on PATH, so a GUI git client without Beacon on its PATH still links commits.
Hooks live in the repository’s shared hooks directory, so one setup covers every linked worktree.
Set
BEACON_GIT_HOOKS=0 to skip the hooks for one command:
Hook managers and core.hooksPath
Tools such as husky and lefthook point core.hooksPath at a directory they own, often one tracked in the repository. setup refuses to write there by default and prints the line to add to that tool’s post-commit hook instead:
--hooks-path to install into that directory anyway.
beacon git status
Shows whether each hook is installed, reports an install that is broken (a hook calling a script that is gone, or the reverse), and says whether notes.rewriteRef is set. --json prints the same as JSON, with a top-level installed field.
Sharing links with a team
Links start out local. Nothing leaves the machine until you share them, and sharing is off unless you turn it on.- Fetching. Each remote gets a fetch refspec,
+refs/notes/beacon:refs/notes/beacon-remotes/<remote>, so a plaingit fetchorgit pullbrings teammates’ links into a read-only copy.beacon git notesreads that copy alongside your own links. Yourrefs/notes/beaconis never overwritten by a fetch, so links you have not pushed yet are safe. A fetch or pull that names a refspec on the command line, such asgit pull origin main, skips configured refspecs; runbeacon git notes fetchto fetch links then. - Pushing. A
pre-pushhook shares your links whenever yougit push. It fetches the remote’s links, merges them with yours (every line of both is kept), and pushes onlyrefs/notes/beaconto the same remote. It runs with--no-verify, so your other pre-push hooks are not run twice. It gives up after ten seconds and never fails your push: if sharing fails, it prints one line and your code is pushed as usual.
BEACON_GIT_HOOKS=0 git push skips it for one push, and beacon git setup --share-notes=false turns it off.
To share by hand instead, without the hook:
beacon:<harness>/<session-id> lines, so sharing a link shares that a session produced the commit, not what happened in it. The session itself stays in the runtime log of the machine that ran it.
beacon git remove
Removes Beacon’s scripts, its blocks in the hooks, its notes.rewriteRef value, and the fetch refspecs --share-notes added, leaving everything else as it was. A hook that held nothing but Beacon’s block is deleted. Links already written stay in refs/notes/beacon.
beacon git link
Links a commit (default HEAD) and writes the note.
Example output
link again adds only what is new. Links already on the commit, including a teammate’s, are kept, as is any other text in the note.
beacon git notes
Lists recent linked commits reachable from a revision (default HEAD).
Runtime log events
Each new link is also recorded in the runtime log as asession.commit_linked event in the linked session’s own timeline, so the dashboard, beacon endpoint traces, handoff briefs, rules and any forwarding destination see the commit alongside the work that produced it. link and the hook record an event only for a link they add: a dry run, or a commit already linked to the session, records nothing.
Example event (abridged)
event.fidelityisinferred: the link is Beacon’s conclusion from file overlap, not something the runtime reported.vcs.ref.head.nameis the branch HEAD was on at commit time. It is empty for a detached HEAD, or for an older commit linked by hand, whose branch git cannot say.vcs.repository.url.fullis the URL of the remote the branch tracks, ororigin, with any user name, token, or query string removed.- The event carries identifiers and counts only: no file paths, diff, or commit message.
main that one session wrote in full:
Note format
Links live underrefs/notes/beacon, one per line:
<harness> is Beacon’s canonical harness name (claude_code, codex_cli, cursor, …). A session id has no whitespace, no control or non-ASCII characters, and at most 256 characters. Readers ignore anything after whitespace on a link line, which is reserved for later fields, and ignore lines that do not start with beacon:.
Beacon updates the note with a compare-and-swap on the notes ref, so two commits made at the same moment in two worktrees of one repository never lose each other’s links.
To see links in git log, including those fetched from remotes: