diff --git a/README.md b/README.md index 2983ffd..fcfcbd5 100644 --- a/README.md +++ b/README.md @@ -1013,8 +1013,8 @@ to an agent as context. The authenticated identity must be a participant of the *requested* message. Each message is preceded by a one-line separator with its sender and send time. Ancestors the caller is not a participant of appear as -`[message not visible to you]` (a recipient added mid-thread cannot read -what came before); non-text bodies appear as a `[non-text message: , +`--- hidden ---` and `[message not visible to you]`, with no sender or time +(a recipient added mid-thread cannot read what came before); non-text bodies appear as a `[non-text message: , bytes]` placeholder. The walk is capped at 100 hops. **Response:** `200 OK`, `text/plain; charset=utf-8`. diff --git a/internal/handlers/thread.go b/internal/handlers/thread.go index fe229b2..5246589 100644 --- a/internal/handlers/thread.go +++ b/internal/handlers/thread.go @@ -230,21 +230,24 @@ type threadEntry struct { // renderThreadText renders the lineage as plain text, root at the top. Each // message gets a one-line separator with sender and send time; non-text // bodies and messages the caller may not read become placeholders, so the -// chain's shape stays visible without leaking content. +// chain's shape stays visible without leaking content. A message the caller +// may not read shows neither its sender nor its time. func renderThreadText(entries []threadEntry) string { var b strings.Builder for i, e := range entries { if i > 0 { b.WriteString("\n\n") } + if !e.Readable { + b.WriteString("--- hidden ---\n[message not visible to you]") + continue + } ts := "draft" if e.TimeSent != nil { ts = time.Unix(int64(*e.TimeSent), 0).UTC().Format(time.RFC3339) } fmt.Fprintf(&b, "--- %s %s ---\n", e.From, ts) switch { - case !e.Readable: - b.WriteString("[message not visible to you]") case !e.Text: fmt.Fprintf(&b, "[non-text message: %s, %d bytes]", e.Type, e.Size) default: diff --git a/internal/handlers/thread_test.go b/internal/handlers/thread_test.go index c2a5337..678af03 100644 --- a/internal/handlers/thread_test.go +++ b/internal/handlers/thread_test.go @@ -28,6 +28,12 @@ func TestRenderThreadText(t *testing.T) { t.Fatalf("missing %q in:\n%s", want, got) } } + if strings.Count(got, "@bob@example.com") != 1 { + t.Fatalf("a message the caller cannot read must not name its sender:\n%s", got) + } + if !strings.Contains(got, "--- hidden ---\n[message not visible to you]") { + t.Fatalf("missing hidden placeholder in:\n%s", got) + } if strings.Index(got, "root body") > strings.Index(got, "latest reply") { t.Fatal("root must come first (top to bottom)") }