Artifact 7e2dfcbd090d5407800001898c37cf9a98f0de10f6a1ae7446a6a657c1538b06:
- File
internal/sync/stubs.go
— part of check-in
[352a0d9e0b]
at
2026-10-22 12:02:50
on branch feat/horizon-cones
— feat(sync): serve the content horizon and send its pragma
A horizon store asked every peer for the whole history and threw away what fell below C on arrival, so a horizon clone cost a dense clone's bandwidth. draft-fossil-horizon-00 §6 lets the request carry the horizon and the origin restrict what it sends.
The client sends `pragma horizon HASH RULE` after its path-cone pragmas on every clone and pull, never horizon-structural, and counts the replies that say `pragma horizon-served content` (HorizonServed on the clone and sync results, internal and public). It still classifies every reply locally, so a horizon-ignorant peer stays correct (§6.3).
The handler reads the pragma into the request's cone and serves it through the existing keep machinery rather than a parallel path: the pull inventory's keep set drops the blobs below the horizon (via ConeReferences.HorizonBelow) and every cluster; the clone walk walks the tree of a held-set check-in only, counts a parent as sent only inside the held set, and sends every sub-manifest node at its row while sending no cluster. A crossing delta is inflated through the same sourceKept test the path cone uses, charged to the round's batch. req-clusters under a horizon answers nothing, and every reply says horizon-served content.
A horizon store refuses, through refuseClone, a dense clone and a horizon whose held set is not inside its own, both computed over the store with horizon.Place. That is the spec's subset test; zit refuses any other C or rule. A path-only store now also refuses a horizon-only request, which keeps every path.
Interop with zit at horizon-rfc bbd1435674 holds both ways: zit clones and pulls at a horizon from the handler, the client from `zit serve`, and each side's horizon store refuses the other's dense clone. (user: [email protected], size: 1555) [annotate] [blame] [check-ins using] [more...]
package sync import ( "github.com/danmestas/go-libfossil/internal/cone" "github.com/danmestas/go-libfossil/simio" ) // CloneOpts configures a clone operation. type CloneOpts struct { StoreCone *cone.Cone // nil is dense; local policy, never synchronized User string // Credentials for clone auth (also default admin user) Password string Version int // Protocol version (default 3) Env *simio.Env // nil defaults to RealEnv Observer Observer // nil defaults to no-op Buggify BuggifyChecker // fault injection for DST (nil = no faults) // PullPhantoms, when set, makes Clone fetch the artifacts the clone // rounds left missing with a follow-up pull session, and fail with a // *PhantomStallError if any are still missing after it. That pull // departs from Section 8.2 of the sync draft, which sends no clone, // pull or push card after clone_seqno 0, so it is off by default. PullPhantoms bool } // CloneResult reports what happened during a clone. type CloneResult struct { Elided int // artifacts deliberately absent under the store cone ConeServed int // replies acknowledging the store cone (sparse-cone §6.3); the rest were filtered locally HorizonServed int // replies serving the content horizon (horizon §6.2.5); the rest were classified locally Rounds int BlobsRecvd int ArtifactsLinked int // Manifests crosslinked into event table ProjectCode string ServerCode string Messages []string // Informational messages from server }