@@ 264,6 264,8 @@ func (r *mutationResolver) UpdateRepository(ctx context.Context, id int, input m
 			}
 			return err
 		}
+
+		webhooks.DeliverLegacyRepoUpdate(ctx, &repo)
 		return nil
 	}); err != nil {
 		if moved && err != nil {
 
@@ 35,27 35,65 @@ func LegacyMiddleware(
 	}
 }
 
+type RepoWebhookPayload struct {
+	ID          int       `json:"id"`
+	Created     time.Time `json:"created"`
+	Updated     time.Time `json:"updated"`
+	Name        string    `json:"name"`
+	Description *string   `json:"description"`
+	Visibility  string    `json:"visibility"`
+
+	Owner struct {
+		CanonicalName string  `json:"canonical_name"`
+		Name          string  `json:"name"`
+	}`json:"owner"`
+}
+
 func DeliverLegacyRepoCreate(ctx context.Context, repo *model.Repository) {
 	q, ok := ctx.Value(legacyUserCtxKey).(*webhooks.LegacyQueue)
 	if !ok {
 		panic(errors.New("No legacy user webhooks worker for this context"))
 	}
 
-	type WebhookPayload struct {
-		ID          int       `json:"id"`
-		Created     time.Time `json:"created"`
-		Updated     time.Time `json:"updated"`
-		Name        string    `json:"name"`
-		Description *string   `json:"description"`
-		Visibility  string    `json:"visibility"`
-
-		Owner struct {
-			CanonicalName string  `json:"canonical_name"`
-			Name          string  `json:"name"`
-		}`json:"owner"`
+	payload := RepoWebhookPayload{
+		ID:          repo.ID,
+		Created:     repo.Created,
+		Updated:     repo.Created,
+		Name:        repo.Name,
+		Description: repo.Description,
+		Visibility:  repo.RawVisibility,
+	}
+
+	// TODO: User groups
+	user := auth.ForContext(ctx)
+	if user.UserID != repo.OwnerID {
+		// At the time of writing, the only consumers of this function are in a
+		// context where the authenticated user is the owner of this repo. We
+		// can skip the database round-trip if we just grab their auth context.
+		panic(errors.New("TODO: look up user details for this repo"))
+	}
+	payload.Owner.CanonicalName = "~" + user.Username
+	payload.Owner.Name = user.Username
+
+	encoded, err := json.Marshal(&payload)
+	if err != nil {
+		panic(err) // Programmer error
 	}
 
-	payload := WebhookPayload{
+	query := sq.
+		Select().
+		From("user_webhook_subscription sub").
+		Where("sub.user_id = ?", repo.OwnerID)
+	q.Schedule(query, "user", "repo:create", encoded)
+}
+
+func DeliverLegacyRepoUpdate(ctx context.Context, repo *model.Repository) {
+	q, ok := ctx.Value(legacyUserCtxKey).(*webhooks.LegacyQueue)
+	if !ok {
+		panic(errors.New("No legacy user webhooks worker for this context"))
+	}
+
+	payload := RepoWebhookPayload{
 		ID:          repo.ID,
 		Created:     repo.Created,
 		Updated:     repo.Created,
@@ 84,5 122,5 @@ func DeliverLegacyRepoCreate(ctx context.Context, repo *model.Repository) {
 		Select().
 		From("user_webhook_subscription sub").
 		Where("sub.user_id = ?", repo.OwnerID)
-	q.Schedule(query, "user", "repo:create", encoded)
+	q.Schedule(query, "user", "repo:update", encoded)
 }