diff --git a/pb_migrations/1796600000_e2e_runs_updated.js b/pb_migrations/1796600000_e2e_runs_updated.js
new file mode 100644
index 0000000..fb4507b
--- /dev/null
+++ b/pb_migrations/1796600000_e2e_runs_updated.js
@@ -0,0 +1,25 @@
+///
+
+// When a run last moved.
+//
+// The collection had `created` and nothing else, so "is this run still alive or
+// did it die" had no answer: the dashboard read a field that was not there, got
+// NaN, and called every live run stalled. `status` alone cannot answer it -- a
+// killed process leaves its record saying `running` for ever -- so the honest
+// signal is the timestamp of the last update.
+
+migrate(
+ (app) => {
+ const runs = app.findCollectionByNameOrId("e2e_runs");
+ runs.fields.add(
+ new AutodateField({ name: "updated", onCreate: true, onUpdate: true }),
+ );
+ app.save(runs);
+ },
+ (app) => {
+ const runs = app.findCollectionByNameOrId("e2e_runs");
+ const f = runs.fields.getByName("updated");
+ if (f) runs.fields.removeById(f.id);
+ app.save(runs);
+ },
+);
diff --git a/pb_public/status.html b/pb_public/status.html
index e37e951..20804c5 100644
--- a/pb_public/status.html
+++ b/pb_public/status.html
@@ -714,9 +714,17 @@ function outcomePill(o){
// deliberately generous and only ever says "stalled", never "failed".
var STALL_MS = 300000;
+// PocketBase hands back "2026-09-10 09:42:49.664Z" — a space instead of the T
+// and the zone already on the end. Appending another Z made every parse NaN,
+// which made every live run look stalled.
+function pbDate(s){
+ var iso = String(s || "").replace(" ", "T");
+ return Date.parse(/[Z+]/.test(iso.slice(10)) ? iso : iso + "Z");
+}
+
function isLive(r){
- return r.status === "running" &&
- (Date.now() - Date.parse(String(r.updated).replace(" ", "T") + "Z")) < STALL_MS;
+ var at = pbDate(r.updated || r.created);
+ return r.status === "running" && !isNaN(at) && (Date.now() - at) < STALL_MS;
}
function isStalled(r){
@@ -742,7 +750,7 @@ function progressBar(r){
'
' + done + " z " + total + "" +
(r.current ? "" + esc(r.current) + "" : "") +
(isStalled(r) ? "naposledy se pohnul " +
- esc(String(r.updated).substring(11, 16)) + "" : "") +
+ esc(String(r.updated || r.created).substring(11, 16)) + "" : "") +
"
";
}