You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
forge: mirror repos on their kind-30618 repository state (opt-in, config.mirror) #12
gitmark 0.0.84 publishes a NIP-34 repository state, kind 30618, after every git mark announce: d = repo name, HEAD, one refs/heads/<branch> tag per branch with its commit, and the mark as chain, txo, commit. It is replaceable, so the newest one from the agent's key says where the repo is now. That is the pull signal a mirror needs: no polling of GitHub or an explorer, one small event per announce.
Proposal: an opt-in mirror in the forge plugin.
config.mirror = { relays: ['wss://…'], follow: [{ pubkey: '<hex>', name: '<repo>', clone: '<url>' }] }. Unset, nothing changes: no sockets, no fetches. The current stance, no chain I/O in the plugin, holds either way; the mirror talks to relays and to git remotes, never to an explorer.
On activate with a non-empty follow list: one WebSocket per relay, one REQ for kinds 30617 and 30618 from the followed pubkeys. The relay filters, so the forge receives only events about repos it mirrors.
A 30618 is acted on only when: the signature verifies; (pubkey, d) is a followed repo; created_at is newer than the last one seen for that repo; and the refs differ from the local bare repo. Then one git fetch from the clone URL (the configured one, or the newest 30617's clone tag from the same key) into refs/mirror/*. A branch is advanced to the state's commit only if that commit was fetched and, when the state carries a mark, the trail file at that commit lists the commit tag. Otherwise the fetch is kept but no ref moves, and the reason is recorded.
The mirrored repo lives at repos/<pubkey>/<name>.git, so it shows in the UI and on the Anchors tab like a pushed repo. pluginDir/mirror/<pubkey>/<name>.json records last event, last fetch and verdict; GET api/repos/<o>/<n>/mirror returns it.
Guards: at most 50 followed repos, one fetch per repo per 30 s, catch-up REQ and backoff on reconnect, ws loaded lazily as for announce. Mirrors are keyed by pubkey plus name, never name alone, since anyone can publish a 30618 with any d.
Out of scope: discovering repos to follow (the follow list is the operator's), and verifying the mark against the chain (that stays in the browser).
Activity