compute_time_accuracy in routes/archives.py compares the archive row's
own started_at / completed_at (which reflect the latest run only)
against archive.print_time_seconds (which the #1593 parser fix
correctly stores as the sum across plates). For a 3-plate file printed
plate-by-plate the ratio is ~300%, producing a "+188%" card badge that
means nothing — apples to oranges. The 5-500% sanity band catches
truly broken values but lets this deterministic N×100% shape through.
Reporter's archive #65 was 3 plates over 9 runs.
compute_time_accuracy gains an optional run_aggregate argument and
returns both actual_time_seconds and time_accuracy as null when the
aggregate reports more than one logged run. The frontend already falls
through to print_time_seconds for the time display
(actual_time_seconds || print_time_seconds) and gates the badge on
time_accuracy being truthy, so multi-run archives now show the slicer
estimate with no badge. Single-run archives keep the original
behaviour verbatim.
The fix is applied at every call site that renders an archive card:
archive_to_response now threads run_aggregate through, and the three
endpoints that previously didn't load the aggregate (archives.py
search fast-path and FTS path, single-archive PATCH, and
projects.list_project_archives) now batch-load it via the existing
_load_run_aggregates helper.
The stats endpoint's per-run accuracy aggregation at archives.py:940
already uses PrintLogEntry.duration_seconds with its own 50-200% band
filter and is untouched.