diff --git a/src/Vervis/Federation.hs b/src/Vervis/Federation.hs
index 41dc9d7..4971bed 100644
--- a/src/Vervis/Federation.hs
+++ b/src/Vervis/Federation.hs
@@ -377,6 +377,8 @@ handleRepoInbox shrRecip rpRecip now auth body = do
             (,Nothing) <$> repoFollowF shrRecip rpRecip now remoteAuthor body mfwd luActivity follow
         OfferActivity (Offer obj target) ->
             case obj of
+                OfferTicket ticket ->
+                    (,Nothing) <$> repoOfferTicketF now shrRecip rpRecip remoteAuthor body mfwd luActivity ticket target
                 OfferDep dep ->
                     repoOfferDepF now shrRecip rpRecip remoteAuthor body mfwd luActivity dep target
                 _ -> return ("Unsupported offer object type for repos", Nothing)
diff --git a/src/Vervis/Federation/Ticket.hs b/src/Vervis/Federation/Ticket.hs
index ca4f934..1dbfb2b 100644
--- a/src/Vervis/Federation/Ticket.hs
+++ b/src/Vervis/Federation/Ticket.hs
@@ -16,6 +16,7 @@
 module Vervis.Federation.Ticket
     ( sharerOfferTicketF
     , projectOfferTicketF
+    , repoOfferTicketF
 
     , sharerCreateTicketF
     , projectCreateTicketF
@@ -62,7 +63,7 @@ import qualified Data.Text.Lazy as TL
 
 import Database.Persist.JSON
 import Network.FedURI
-import Web.ActivityPub hiding (Ticket (..))
+import Web.ActivityPub hiding (Patch, Ticket (..))
 import Yesod.ActivityPub
 import Yesod.FedURI
 import Yesod.Hashids
@@ -185,7 +186,15 @@ checkOfferTicket author ticket uTarget = do
             case branch of
                 Left (shr', rp', mb) | shr == shr' && rp == rp' -> return mb
                 _ -> throwE "MR target repo/branch and Offer target repo mismatch"
-        return $ Left $ WTTRepo shr rp branch' (typ2vcs typ) content
+        let vcs = typ2vcs typ
+        case vcs of
+            VCSDarcs ->
+                unless (isNothing branch') $
+                    throwE "Darcs MR specifies a branch"
+            VCSGit ->
+                unless (isJust branch') $
+                    throwE "Git MR doesn't specify the branch"
+        return $ Left $ WTTRepo shr rp branch' vcs content
         where
         typ2vcs PatchTypeDarcs = VCSDarcs
     matchTargetAndMR (Right (ObjURI h lu)) Nothing = return $ Right (h, lu, Nothing)
@@ -235,6 +244,37 @@ sharerOfferTicketF now shrRecip author body mfwd luOffer ticket uTarget = do
             Nothing -> "Activity already exists in my inbox"
             Just _ -> "Activity inserted to my inbox"
 
+insertLocalTicket now author txl summary content source ractidOffer obiidAccept = do
+    did <- insert Discussion
+    fsid <- insert FollowerSet
+    tid <- insert Ticket
+        { ticketNumber      = Nothing
+        , ticketCreated     = now
+        , ticketTitle       = unTextHtml summary
+        , ticketSource      = unTextPandocMarkdown source
+        , ticketDescription = unTextHtml content
+        , ticketAssignee    = Nothing
+        , ticketStatus      = TSNew
+        , ticketClosed      = UTCTime (ModifiedJulianDay 0) 0
+        , ticketCloser      = Nothing
+        }
+    ltid <- insert LocalTicket
+        { localTicketTicket    = tid
+        , localTicketDiscuss   = did
+        , localTicketFollowers = fsid
+        }
+    tclid <- insert TicketContextLocal
+        { ticketContextLocalTicket = tid
+        , ticketContextLocalAccept = obiidAccept
+        }
+    insert_ $ txl tclid
+    insert_ TicketAuthorRemote
+        { ticketAuthorRemoteTicket = tclid
+        , ticketAuthorRemoteAuthor = remoteAuthorId author
+        , ticketAuthorRemoteOpen   = ractidOffer
+        }
+    return (tid, ltid)
+
 projectOfferTicketF
     :: UTCTime
     -> ShrIdent
@@ -269,7 +309,7 @@ projectOfferTicketF now shrRecip prjRecip author body mfwd luOffer ticket uTarge
                 (sig,) <$> deliverRemoteDB_J (actbBL body) ractid jid sig remoteRecips
             (obiidAccept, docAccept, fwdHostsAccept, recipsAccept) <- do
                 obiidAccept <- insertEmptyOutboxItem (projectOutbox j) now
-                ltid <- insertTicket now author jid summary content source ractid obiidAccept
+                (_, ltid) <- insertLocalTicket now author (flip TicketProjectLocal jid) summary content source ractid obiidAccept
                 (docAccept, localRecipsAccept, remoteRecipsAccept, fwdHostsAccept) <-
                     insertAccept shrRecip prjRecip author luOffer ltid obiidAccept
                 knownRemoteRecipsAccept <-
@@ -301,39 +341,6 @@ projectOfferTicketF now shrRecip prjRecip author body mfwd luOffer ticket uTarge
     targetRelevance (Left (WTTProject shr prj))
         | shr == shrRecip && prj == prjRecip = Just ()
     targetRelevance _ = Nothing
-    insertTicket now author jid summary content source ractidOffer obiidAccept = do
-        did <- insert Discussion
-        fsid <- insert FollowerSet
-        tid <- insert Ticket
-            { ticketNumber      = Nothing
-            , ticketCreated     = now
-            , ticketTitle       = unTextHtml summary
-            , ticketSource      = unTextPandocMarkdown source
-            , ticketDescription = unTextHtml content
-            , ticketAssignee    = Nothing
-            , ticketStatus      = TSNew
-            , ticketClosed      = UTCTime (ModifiedJulianDay 0) 0
-            , ticketCloser      = Nothing
-            }
-        ltid <- insert LocalTicket
-            { localTicketTicket    = tid
-            , localTicketDiscuss   = did
-            , localTicketFollowers = fsid
-            }
-        tclid <- insert TicketContextLocal
-            { ticketContextLocalTicket = tid
-            , ticketContextLocalAccept = obiidAccept
-            }
-        insert_ TicketProjectLocal
-            { ticketProjectLocalContext = tclid
-            , ticketProjectLocalProject = jid
-            }
-        insert_ TicketAuthorRemote
-            { ticketAuthorRemoteTicket = tclid
-            , ticketAuthorRemoteAuthor = remoteAuthorId author
-            , ticketAuthorRemoteOpen   = ractidOffer
-            }
-        return ltid
     insertAccept shr prj author luOffer ltid obiidAccept = do
         encodeRouteLocal <- getEncodeRouteLocal
         encodeRouteHome <- getEncodeRouteHome
@@ -375,6 +382,116 @@ projectOfferTicketF now shrRecip prjRecip author body mfwd luOffer ticket uTarge
         update obiidAccept [OutboxItemActivity =. persistJSONObjectFromDoc doc]
         return (doc, recipientSet, remoteActors, fwdHosts)
 
+repoOfferTicketF
+    :: UTCTime
+    -> ShrIdent
+    -> RpIdent
+    -> RemoteAuthor
+    -> ActivityBody
+    -> Maybe (LocalRecipientSet, ByteString)
+    -> LocalURI
+    -> AP.Ticket URIMode
+    -> FedURI
+    -> ExceptT Text Handler Text
+repoOfferTicketF now shrRecip rpRecip author body mfwd luOffer ticket uTarget = do
+    (target, summary, content, source) <- checkOfferTicket author ticket uTarget
+    mmhttp <- for (targetRelevance target) $ \ (mb, vcs, diff) -> runDBExcept $ do
+        Entity rid r <- lift $ do
+            sid <- getKeyBy404 $ UniqueSharer shrRecip
+            getBy404 $ UniqueRepo rpRecip sid
+        unless (repoVcs r == vcs) $ throwE "Patch type and repo VCS mismatch"
+        mractid <- lift $ insertToInbox now author body (repoInbox r) luOffer False
+        lift $ for mractid $ \ ractid -> do
+            mremotesHttpFwd <- for mfwd $ \ (localRecips, sig) -> do
+                let sieve =
+                        makeRecipientSet
+                            []
+                            [ LocalPersonCollectionRepoTeam shrRecip rpRecip
+                            , LocalPersonCollectionRepoFollowers shrRecip rpRecip
+                            ]
+                remoteRecips <-
+                    insertRemoteActivityToLocalInboxes
+                        False ractid $
+                            localRecipSieve'
+                                sieve False False localRecips
+                (sig,) <$> deliverRemoteDB_R (actbBL body) ractid rid sig remoteRecips
+            (obiidAccept, docAccept, fwdHostsAccept, recipsAccept) <- do
+                obiidAccept <- insertEmptyOutboxItem (repoOutbox r) now
+                let makeTRL tclid = TicketRepoLocal tclid rid mb
+                (tid, ltid) <- insertLocalTicket now author makeTRL summary content source ractid obiidAccept
+                insert_ $ Patch tid now diff
+                (docAccept, localRecipsAccept, remoteRecipsAccept, fwdHostsAccept) <-
+                    insertAccept shrRecip rpRecip author luOffer ltid obiidAccept
+                knownRemoteRecipsAccept <-
+                    deliverLocal'
+                        False
+                        (LocalActorRepo shrRecip rpRecip)
+                        (repoInbox r)
+                        obiidAccept
+                        localRecipsAccept
+                (obiidAccept,docAccept,fwdHostsAccept,) <$>
+                    deliverRemoteDB'' fwdHostsAccept obiidAccept remoteRecipsAccept knownRemoteRecipsAccept
+            return (mremotesHttpFwd, obiidAccept, docAccept, fwdHostsAccept, recipsAccept)
+    case mmhttp of
+        Nothing -> return "Offer target isn't me, not using"
+        Just mhttp ->
+            case mhttp of
+                Nothing -> return "Activity already in my inbox, doing nothing"
+                Just (mremotesHttpFwd, obiid, doc, fwdHosts, remotes) -> do
+                    for_ mremotesHttpFwd $ \ (sig, remotes) ->
+                        forkWorker "repoOfferTicketF inbox-forwarding" $
+                            deliverRemoteHTTP_R now shrRecip rpRecip (actbBL body) sig remotes
+                    forkWorker "repoOfferTicketF Accept HTTP delivery" $
+                        deliverRemoteHttp' fwdHosts obiid doc remotes
+                    return $
+                        case mremotesHttpFwd of
+                            Nothing -> "Accepted new patch, no inbox-forwarding to do"
+                            Just _ -> "Accepted new patch and ran inbox-forwarding of the Offer"
+    where
+    targetRelevance (Left (WTTRepo shr rp mb vcs diff))
+        | shr == shrRecip && rp == rpRecip = Just (mb, vcs, diff)
+    targetRelevance _ = Nothing
+    insertAccept shr rp author luOffer ltid obiidAccept = do
+        encodeRouteLocal <- getEncodeRouteLocal
+        encodeRouteHome <- getEncodeRouteHome
+
+        hLocal <- asksSite siteInstanceHost
+
+        obikhidAccept <- encodeKeyHashid obiidAccept
+        ltkhid <- encodeKeyHashid ltid
+
+        ra <- getJust $ remoteAuthorId author
+
+        let ObjURI hAuthor luAuthor = remoteAuthorURI author
+
+            audAuthor =
+                AudRemote hAuthor [luAuthor] (maybeToList $ remoteActorFollowers ra)
+            audProject =
+                AudLocal []
+                    [ LocalPersonCollectionRepoTeam shr rp
+                    , LocalPersonCollectionRepoFollowers shr rp
+                    ]
+
+            (recipientSet, remoteActors, fwdHosts, audLocal, audRemote) =
+                collectAudience [audAuthor, audProject]
+
+            recips = map encodeRouteHome audLocal ++ audRemote
+            doc = Doc hLocal Activity
+                { activityId       =
+                    Just $ encodeRouteLocal $
+                        RepoOutboxItemR shr rp obikhidAccept
+                , activityActor    = encodeRouteLocal $ RepoR shr rp
+                , activitySummary  = Nothing
+                , activityAudience = Audience recips [] [] [] [] []
+                , activitySpecific = AcceptActivity Accept
+                    { acceptObject = ObjURI hAuthor luOffer
+                    , acceptResult =
+                        Just $ encodeRouteLocal $ RepoPatchR shr rp ltkhid
+                    }
+                }
+        update obiidAccept [OutboxItemActivity =. persistJSONObjectFromDoc doc]
+        return (doc, recipientSet, remoteActors, fwdHosts)
+
 checkCreateTicket
     :: RemoteAuthor
     -> AP.Ticket URIMode