feat: bakeoff record --note; Spinel load results

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paul Campbell pushed by claude agent, operated by paul@keymail.dev 793a4531b9a2b4e05adbec0f6f4cbbc182000601 parent 3618d3e
5 files changed, +20 −3
  • harness/apps.go +2 −1
  • harness/cmd/bakeoff/main.go +1 −0
  • harness/harness_test.go +9 −0
  • harness/results.go +5 −1
  • results/spinel.json +3 −1
diff --git a/harness/apps.go b/harness/apps.go
index 0e93631..c64b471 100644
--- a/harness/apps.go
+++ b/harness/apps.go
@@ -43,4 +43,5 @@ func Host(slug string) string {
// load), and a used database can't be reset, so it was measured on a third
// fresh instance (2026-10-24).
var hostOverride = map[string]string{"spinel": "todo-spinel-3.bfj.oncarlos.com"}
-func URL(slug string) string { return "https://" + Host(slug) }
+
+func URL(slug string) string { return "https://" + Host(slug) }
diff --git a/harness/cmd/bakeoff/main.go b/harness/cmd/bakeoff/main.go
index a523a56..4a11a06 100644
--- a/harness/cmd/bakeoff/main.go
+++ b/harness/cmd/bakeoff/main.go
@@ -45,6 +45,7 @@ func main() {
fs.StringVar(&rec.Version, "version", "", "record: deployed version")
fs.StringVar(&rec.Stack, "stack", "", "record: one-line stack summary")
fs.StringVar(&rec.Source, "source", "", "record: source URL")
+ fs.StringVar(&rec.Note, "note", "", "record: a note shown in the app's section (added once)")
recURL := fs.String("app-url", "", "record: live URL")
replies := fs.String("replies", "", "readability: comma-separated files, one scorer reply each")
fs.Parse(os.Args[2:])
diff --git a/harness/harness_test.go b/harness/harness_test.go
index 413ced9..3d93025 100644
--- a/harness/harness_test.go
+++ b/harness/harness_test.go
@@ -322,3 +322,12 @@ func TestKneeStopsAtErrors(t *testing.T) {
t.Fatalf("got %+v: want slow-down 64 (last clean step), errors from 128, peak from clean steps only", k)
}
}
+
+func TestApplyRecordAppendsNoteOnce(t *testing.T) {
+ r := AppResult{}
+ ApplyRecord(&r, Record{Note: "exits under load"})
+ ApplyRecord(&r, Record{Note: "exits under load"})
+ if len(r.Notes) != 1 || r.Notes[0] != "exits under load" {
+ t.Fatalf("got %q", r.Notes)
+ }
+}
diff --git a/harness/results.go b/harness/results.go
index 8e810ad..0d12ee8 100644
--- a/harness/results.go
+++ b/harness/results.go
@@ -6,6 +6,7 @@ import (
"io/fs"
"os"
"path/filepath"
+ "slices"
)
// ResultsDir is where results/<slug>.json live, relative to the repo root.
@@ -75,7 +76,7 @@ func Update(slug string, f func(*AppResult)) error { return UpdateIn(ResultsDir,
// Record is a partial update of an app's identity fields; empty fields
// leave the stored value alone.
-type Record struct{ Language, Status, URL, Version, Stack, Source string }
+type Record struct{ Language, Status, URL, Version, Stack, Source, Note string }
// ApplyRecord copies the non-empty fields of rec into r.
func ApplyRecord(r *AppResult, rec Record) {
@@ -90,4 +91,7 @@ func ApplyRecord(r *AppResult, rec Record) {
set(&r.Version, rec.Version)
set(&r.Stack, rec.Stack)
set(&r.Source, rec.Source)
+ if rec.Note != "" && !slices.Contains(r.Notes, rec.Note) {
+ r.Notes = append(r.Notes, rec.Note)
+ }
}
diff --git a/results/spinel.json b/results/spinel.json
index 2d26765..c7d65f8 100644
--- a/results/spinel.json
+++ b/results/spinel.json
@@ -102,5 +102,7 @@
"[correctness] `apps/spinel/patches/2-tep-bakeoff.patch:330` — URL decoding turns `%00` into a NUL inside a C string, which is then truncated when copied into Ruby. Posting `title=before%00after` silently stores `before`; editing with `title=%00after` deletes the todo. Preserve decoded string lengths so input cannot silently become a different title or action.",
"[spec] `apps/spinel/Makefile:130` — `clean-deps` deletes only the local SQLite and tep artifacts. The arm64 build still links precompiled OpenSSL, zlib and zstd libraries from the shared toolchain root (`scripts/arm64-cc:21`), so the next build does not compile every third-party library from scratch as required. Build those dependencies into the app’s own cache and include them in `clean-deps`."
],
- "Notes": null
+ "Notes": [
+ "Its server process exited (status 0) 10 times during the load test, and Carloku restarted it each time; the edge answered 502 in between."
+ ]
}