import { VersionInfo } from '@start9labs/start-sdk' export const v_0_2_28 = VersionInfo.of({ version: '0.2.28:0', releaseNotes: { en_US: 'Output storage + parallel benchmark pairs + storage management. (1) Every test-run job\'s transcript + analysis JSON is now persisted to /data/relay-outputs/.json after the job completes. Real-user traffic is opt-in via a new relay_save_user_outputs config flag (default false, set via StartOS action). (2) The Jobs table gains a "View" column with a 👁 link on each row that has a stored output — opens a new tab showing a Recap-style two-pane render: topic list on the left, transcript with timestamps on the right, click any topic to scroll the transcript to that range and highlight the matching entries. The view page is public/job-output-view.html — admin-auth-gated like the rest of /admin/*. (3) Row-level checkboxes on the Jobs table let you select a subset of rows; new "Stored outputs" mini-panel above the table shows total count + size + Delete-selected and Delete-all buttons. Audit log rows are NEVER deleted alongside outputs — only the saved transcript+analysis JSONs. (4) New admin endpoints: GET /admin/job-output/:id, GET /admin/output-store-stats, GET /admin/output-store-ids, DELETE /admin/job-outputs (body {job_ids:[...]} or {all:true}). (5) Benchmark suite now runs paired permutations CONCURRENTLY instead of sequentially — perms 1+6 (shared TX = gemini-3.1-flash-lite), 4+5 (shared TX = hardware), 7+8 (shared captions) each fire as a single "phase" with two in-flight permutations. The relay\'s new TX-share cache ensures the underlying transcribe runs ONCE per phase; the paired permutation awaits the in-flight Promise and reuses the resulting transcript at zero additional TX cost or wall time. Audit rows from the cached side are stamped source="admin-test-shared-tx" so the dashboard can identify them. Net effect: a full 8-permutation YouTube suite drops from 8 sequential transcribes to 5 (pairs collapse), typically cutting total wall time by 30-40% on long content. (6) Spark Control live model pull was already wired in via hardware-config.js — the audit log already records the live model name returned by Spark Control\'s /api/endpoints (with a 60s cache), so model swaps on the Spark side are reflected within ~1 minute without any relay config change.', }, migrations: { up: async ({ effects }) => {}, down: async ({ effects }) => {}, }, })