autoresearch iter 8: render synthesized notification content in stable order

bodyContent's fallback ranged over the body map, and Go randomizes map
iteration, so the same notification rendered its fields in a different order
on every send. Observed failing before the fix: the second call already
reordered the output. Iterate sorted keys instead.
This commit is contained in:
ryan
2026-08-29 08:23:23 +08:00
parent 03f48a9a80
commit 18820b17f6
2 changed files with 27 additions and 2 deletions
@@ -6,6 +6,8 @@ package push
import (
"encoding/json"
"fmt"
"maps"
"slices"
"strconv"
"strings"
)
@@ -87,13 +89,15 @@ func bodyTitle(body map[string]any) string {
// bodyContent returns the notification body, rendering every entry with format
// (a "%s … %v" pair) and joining them with sep when no content field is given.
// Entries render in sorted key order so identical bodies always produce
// identical text.
func bodyContent(body map[string]any, format, sep string) string {
if c, ok := body["content"].(string); ok && c != "" {
return c
}
parts := make([]string, 0, len(body))
for k, v := range body {
parts = append(parts, fmt.Sprintf(format, k, v))
for _, k := range slices.Sorted(maps.Keys(body)) {
parts = append(parts, fmt.Sprintf(format, k, body[k]))
}
return strings.Join(parts, sep)
}