Skip to content

forge: mirror repos on their kind-30618 repository state (opt-in, config.mirror) #12

Closed

Description

@melvincarvalho

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions