From 76fa9f2d499055475bf7be6c527bd723e80c4511 Mon Sep 17 00:00:00 2001 From: Daniel Rosales <111561081+dnlrsls@users.noreply.github.com> Date: Mon, 28 Sep 2026 22:42:17 -0500 Subject: [PATCH] feat(cloud): expose prompt authority calls to autosync --- cmd/engram/autosync_e2e_test.go | 44 +++++++++++++++++++++++++++++++++ cmd/engram/main.go | 8 ++++++ 2 files changed, 52 insertions(+) diff --git a/cmd/engram/autosync_e2e_test.go b/cmd/engram/autosync_e2e_test.go index daadf4050..12680a4b6 100644 --- a/cmd/engram/autosync_e2e_test.go +++ b/cmd/engram/autosync_e2e_test.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "reflect" "sync" "sync/atomic" "testing" @@ -18,6 +19,49 @@ import ( _ "modernc.org/sqlite" ) +func TestMutationTransportAdapterForwardsPromptAuthority(t *testing.T) { + var paths []string + var bodies []map[string]string + srv := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.TLS == nil || r.Method != http.MethodPost || r.Header.Get("Authorization") != "Bearer test-token" { + t.Errorf("unexpected request security or method: TLS=%v method=%s auth=%q", r.TLS != nil, r.Method, r.Header.Get("Authorization")) + http.Error(w, "unauthorized", http.StatusUnauthorized) + return + } + var body map[string]string + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Errorf("decode request: %v", err) + http.Error(w, "invalid request", http.StatusBadRequest) + return + } + paths = append(paths, r.URL.Path) + bodies = append(bodies, body) + _ = json.NewEncoder(w).Encode(map[string]string{"status": "ok"}) + })) + defer srv.Close() + trustTLSServer(t, srv) + + mt, err := remote.NewMutationTransport(srv.URL, "test-token") + if err != nil { + t.Fatal(err) + } + adapter := &mutationTransportAdapter{remote: mt} + if err := adapter.RegisterSessionAuthority("session-1", "alpha"); err != nil { + t.Fatal(err) + } + if err := adapter.ClaimPromptPair("session-1", "inbox-2", "sync-3", "alpha", "beta"); err != nil { + t.Fatal(err) + } + wantPaths := []string{"/sync/session-authorities", "/sync/prompt-pair-claims"} + wantBodies := []map[string]string{ + {"session_id": "session-1", "project": "alpha"}, + {"session_id": "session-1", "source_inbox_id": "inbox-2", "sync_id": "sync-3", "owner_project": "alpha", "project": "beta"}, + } + if !reflect.DeepEqual(paths, wantPaths) || !reflect.DeepEqual(bodies, wantBodies) { + t.Fatalf("requests: paths=%v bodies=%v; want paths=%v bodies=%v", paths, bodies, wantPaths, wantBodies) + } +} + // ─── E2E Round-trip test (REQ-212) ─────────────────────────────────────────── // TestAutosyncPushPullRoundTrip tests the full push/pull cycle using a real diff --git a/cmd/engram/main.go b/cmd/engram/main.go index 18b13983c..81edee472 100644 --- a/cmd/engram/main.go +++ b/cmd/engram/main.go @@ -316,6 +316,14 @@ type mutationTransportAdapter struct { remote *remote.MutationTransport } +func (a *mutationTransportAdapter) RegisterSessionAuthority(sessionID, ownerProject string) error { + return a.remote.RegisterSessionAuthority(sessionID, ownerProject) +} + +func (a *mutationTransportAdapter) ClaimPromptPair(sessionID, inboxID, syncID, ownerProject, promptProject string) error { + return a.remote.ClaimPromptPair(sessionID, inboxID, syncID, ownerProject, promptProject) +} + func (a *mutationTransportAdapter) PushMutations(entries []autosync.MutationEntry) (*autosync.PushMutationsResult, error) { remoteEntries := make([]remote.MutationEntry, len(entries)) for i, e := range entries {