diff --git a/internal/provider/gitea_comments_test.go b/internal/provider/gitea_comments_test.go index 80c1f4c..05038a6 100644 --- a/internal/provider/gitea_comments_test.go +++ b/internal/provider/gitea_comments_test.go @@ -2,8 +2,10 @@ package provider import ( "context" + "encoding/json" "net/http" "net/http/httptest" + "strings" "testing" "orchestra/internal/domain" @@ -84,3 +86,35 @@ func TestGiteaCommentsRejectsUnparsableCursorAndHTTPError(t *testing.T) { t.Fatal("http failure must be reported") } } + +// The issue body is the task's own statement of what it wants. It must reach +// the store, because every rendered context ranks it above continuity and +// below only a human decision. +func TestGiteaIngestCarriesTheIssueBody(t *testing.T) { + body := `[{"number":1,"title":"Add a --version flag","body":"Print one version line and exit 0. Keep --help working.","state":"open"}]` + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(body)) + })) + defer srv.Close() + out := &sink{} + g := Gitea{BaseURL: srv.URL, Owner: "kami", Repo: "test-e2e", Project: "test-e2e"} + if _, err := g.Poll(context.Background(), out); err != nil { + t.Fatal(err) + } + if len(out.events) != 1 { + t.Fatalf("events = %d", len(out.events)) + } + var p struct { + Title string `json:"title"` + Description string `json:"description"` + } + if err := json.Unmarshal(out.events[0].Payload, &p); err != nil { + t.Fatal(err) + } + if p.Title == "" { + t.Fatal("title missing") + } + if !strings.Contains(p.Description, "Keep --help working") { + t.Fatalf("description = %q", p.Description) + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index c93282b..df86a77 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -302,7 +302,11 @@ func (g Gitea) event(issue giteaIssue, source, project string) domain.Event { for _, l := range issue.Labels { caps = append(caps, l.Name) } - p := map[string]any{"source": source, "external_id": strconv.Itoa(issue.Number), "project": project, "title": issue.Title, "capability": caps} + // The body is the task's own statement of what it wants, which is rank-one + // authority in every rendered context. Dropping it here made every + // Gitea-sourced task run on its title alone, with "Acceptance: Not stated." + // Found on the first burn-in task, 2026-08-26. + p := map[string]any{"source": source, "external_id": strconv.Itoa(issue.Number), "project": project, "title": issue.Title, "description": issue.Body, "capability": caps} b, _ := json.Marshal(p) return domain.Event{ID: domain.NewID(), TaskID: domain.NewID(), Type: "TaskCreated", Version: 1, Payload: b, Surface: string(authz.System)} }