Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
6875b85
[API] Design and implement the v5 API
ldionne Mar 31, 2026
c4ec442
[UI] v5 UI Design and implementation
ldionne Apr 3, 2026
dba78fa
[UI] Add exhaustive page-level tests for v5 UI pages
ldionne Apr 6, 2026
fd70e40
[UI] Compare chart: log₂ scale with adaptive percentage tick labels
ldionne Apr 6, 2026
7bfeb8c
[UI] Move v5 UI link to top-right of v4 nav bar
ldionne Apr 6, 2026
7edf0f3
[UI] Fix Cmd+Click on SPA links and brand 404 in admin context
ldionne Apr 7, 2026
1ddfdf5
[UI] Move Graph and Compare pages to suite-agnostic routes
ldionne Apr 7, 2026
7394c9f
[UI] Replace pinned orders with cross-suite baselines on Graph page
ldionne Apr 7, 2026
b49783b
[UI] Fix baseline review issues: cleanup leak, metric re-fetch, stale…
ldionne Apr 7, 2026
0aa585b
[UI] Fix Graph suite selector width: move into controls row
ldionne Apr 7, 2026
0d21904
[UI] Fix baseline form layout and UX issues
ldionne Apr 7, 2026
0471f93
[UI] Align Machines and Baselines labels in graph controls
ldionne Apr 7, 2026
0ef2553
[UI] Refactor order picker: extract reusable component, fix Compare p…
ldionne Apr 7, 2026
3efc032
[API] Add order exact-match parameter to GET /query endpoint
ldionne Apr 7, 2026
390a30c
[UI] Fix baseline rendering: use order exact-match for data fetch
ldionne Apr 7, 2026
7a00d63
[UI] Combobox validation, keyboard nav, and fetch-once machine lists
ldionne Apr 7, 2026
6c0f5d8
[API] Add multi-value test to POST /query and machine/metric filters …
ldionne Apr 7, 2026
0f4136a
[UI] Optimize Graph page with per-test caching, hard cap, and POST /q…
ldionne Apr 7, 2026
59a0932
[UI] Reorganize navbar: flatten to suite-agnostic links, add API/Test…
ldionne Apr 8, 2026
2fd12db
[API] Add /llms.txt endpoint for AI agent orientation
ldionne Apr 8, 2026
39db73d
[UI] Refactor Graph page: introduce GraphDataCache, fix rendering bugs
ldionne Apr 8, 2026
275b925
[UI] Implement Test Suites page with suite picker and browsing tabs
ldionne Apr 8, 2026
3bd3cca
[UI] Fix broken cross-context links on detail pages
ldionne Apr 8, 2026
9b848eb
Rename stale "pinned order" references to "baseline"
ldionne Apr 10, 2026
6a88cdf
[UI] Color baseline traces to match their test's main trace
ldionne Apr 10, 2026
20f3b7d
[Docs] Sync Graph page design/plan with actual test discovery cap beh…
ldionne Apr 10, 2026
08f6b50
[UI] Implement Dashboard page with sparkline trend overview
ldionne Apr 10, 2026
bab5765
[API+UI] Add trends endpoint for server-side geomean aggregation
ldionne Apr 10, 2026
8e70a39
[Docs] Sync Dashboard/trends docs with implementation, remove dead qu…
ldionne Apr 11, 2026
dde50c1
[API] Push trends geomean aggregation to SQL for ~4 orders of magnitu…
ldionne Apr 11, 2026
a3701d1
[UI] Replace Graph page discovery cap with explicit test selection
ldionne Apr 11, 2026
7b8ac8d
[Tests] Decouple v5 API tests from DB layer by using JSON API submiss…
ldionne Apr 13, 2026
4c3d1d5
[Docs] Align design/implementation plan naming with actual API conven…
ldionne Apr 13, 2026
956a7d0
[UI] Show disabled metric dropdown instead of text placeholder
ldionne Apr 13, 2026
67f683c
[UI] Extract DOUBLE_CLICK_DELAY_MS constant to utils
ldionne Apr 13, 2026
2809893
[DB] Add v5 database layer with Commit model
ldionne Apr 13, 2026
eb8ac5b
[API] Rewrite foundation: middleware, helpers, schemas, test infra fo…
ldionne Apr 14, 2026
6b90eb6
[API] Rewrite read-only endpoints (discovery, agents, tests, samples)…
ldionne Apr 14, 2026
72f831e
[API] Rewrite runs endpoint for v5 DB
ldionne Apr 14, 2026
0f7278f
[API] Rewrite machines endpoint for v5 DB
ldionne Apr 14, 2026
80db80c
[API] Rewrite test_suites endpoint for v5 DB
ldionne Apr 14, 2026
1cfaf43
[API] Rewrite admin endpoint for v5 DB
ldionne Apr 14, 2026
762a98a
[API] Create commits endpoint, delete orders endpoint
ldionne Apr 14, 2026
a542270
[API] Rewrite trends endpoint for v5 DB
ldionne Apr 14, 2026
3160e92
[API] Rewrite field_changes endpoint for v5 DB
ldionne Apr 14, 2026
05f27ac
[API] Rewrite regressions endpoint for v5 DB
ldionne Apr 14, 2026
0acd983
[API] Rewrite query endpoint for v5 DB
ldionne Apr 14, 2026
5fa486c
[Docs] Update stale Orders section to Commits in API design doc
ldionne Apr 14, 2026
9bf151f
[Tests] Update 5 cross-cutting test files for v5 DB
ldionne Apr 14, 2026
23e8e34
[DB] Move v5 table creation to `lnt create`, fix concurrent startup c…
ldionne Apr 14, 2026
934da19
[UI] Rebase foundation types and API client from Order to Commit
ldionne Apr 14, 2026
f945112
[UI] Rebase Test Suites page from Order to Commit
ldionne Apr 14, 2026
4c470d3
[UI] Rename Order Detail to Commit Detail, add display field support
ldionne Apr 14, 2026
31188b5
[UI] Clean up stale tag/order terminology in commit-detail
ldionne Apr 14, 2026
2835351
[UI] Rename Order Search to Commit Search
ldionne Apr 14, 2026
e0d33d3
[UI] Rebase Run Detail and Machine Detail pages from Order to Commit
ldionne Apr 14, 2026
91e0aa1
[UI] Rebase Graph page, data cache and chart from Order to Commit
ldionne Apr 14, 2026
5571031
[UI] Rebase combobox, selection and compare from Order to Commit
ldionne Apr 14, 2026
cbaec71
[UI] Final cleanup of stale Order references and design doc sync
ldionne Apr 14, 2026
de33831
[UI] Fix Dashboard runtime bugs from Order→Commit rebase
ldionne Apr 15, 2026
f5d41c1
[Docker] Fix v5 deployment bugs and add end-to-end smoke test
ldionne Apr 15, 2026
cce0470
[DB] Fix multi-worker schema staleness: check freshness on every API …
ldionne Apr 15, 2026
df80342
[Tests+UI] Restore items dropped during v5 DB layer rebase
ldionne Apr 15, 2026
af1c7d9
[Docs] Merge regression workflow redesign into main design docs
ldionne Apr 15, 2026
8f184cd
[Docs] Redesign regression model: drop FieldChange, simplify indicators
ldionne Apr 15, 2026
f182b56
[DB] Implement redesigned regression model: drop FieldChange, new ind…
ldionne Apr 15, 2026
85ceeee
[Docs] Add implementation plans for regression DB and API rewrites
ldionne Apr 15, 2026
310a2ad
[API] Implement redesigned regression model: drop FieldChange, new in…
ldionne Apr 15, 2026
a5effa1
[API+Docs] Add missing OpenAPI schemas and update llms.txt
ldionne Apr 15, 2026
d545606
fixup! [API] Implement redesigned regression model: drop FieldChange,…
ldionne Apr 15, 2026
f5d687c
[Style] Fix flake8 errors from regression model redesign
ldionne Apr 15, 2026
ebceef3
[UI] Fix metric type case mismatch breaking all metric features
ldionne Apr 15, 2026
cbbef68
[UI] Return 404 for nonexistent test suites in v5 SPA catch-all
ldionne Apr 15, 2026
520630c
[UI] Implement regression list, detail, and cross-page integration
ldionne Apr 15, 2026
5b2517f
[Docs] Split design docs into hierarchical structure
ldionne Apr 16, 2026
de6fef4
[UI] Add Regressions tab to Test Suites and "Show all" link to Machin…
ldionne Apr 16, 2026
501c13a
[Tests] Fix compare page JS test failures from regression integration
ldionne Apr 16, 2026
a533048
Disable profiles tests for now
ldionne Apr 16, 2026
8ac94c6
[UI] Add TypeScript type checking to CI and fix scoping bugs
ldionne Apr 16, 2026
3ab02f5
[DB] Fix concurrent submission race condition in get-or-create methods
ldionne Apr 16, 2026
d22c6b4
[DB] Rename APIKey table and columns from PascalCase to snake_case
ldionne Apr 16, 2026
2a68640
[UI] Merge regression list into Test Suites Regressions tab
ldionne Apr 16, 2026
06d247f
[DB] Reject unknown field/metric names instead of silently dropping
ldionne Apr 16, 2026
932ba16
[API+UI] Fix Graph page X-axis to use ordinal ordering
ldionne Apr 16, 2026
88e4c30
[UI] Reorganize detail page layouts and remove run regressions
ldionne Apr 17, 2026
c53efaf
[API] Fix inclusive time bounds in /trends to use exclusive (>/< not …
ldionne Apr 17, 2026
8587b62
[Tests] Add boundary auth/scope enforcement tests for all protected e…
ldionne Apr 17, 2026
43e4290
[UI+API] Regression detail UX batch: notes guard, select-all, shift+c…
ldionne Apr 17, 2026
dd4cef1
[API+DB] Switch v5 to timezone-aware UTC datetimes and Z suffix
ldionne Apr 17, 2026
4f85684
[API] Throttle last_used_at updates to once per hour
ldionne Apr 17, 2026
83e062d
[Docs] Consolidate 7 stale implementation plans into a single guide
ldionne Apr 17, 2026
9cf07f4
[API] Validate serializer output against marshmallow response schemas
ldionne Apr 17, 2026
742edcc
[UI] Compare page: remove noise-hidden rows from DOM, only include vi…
ldionne Apr 17, 2026
3200f0b
[DB+UI] Fix SPA shell not refreshing test suite cache across workers
ldionne Apr 17, 2026
73f4044
[API] Add POST /commits/resolve for batch commit lookups
ldionne Apr 18, 2026
f1ad53f
[UI] Show commit display values across the v5 SPA
ldionne Apr 19, 2026
5957c1a
Add performance audit TODO list
ldionne Apr 20, 2026
0f7af8c
[DB+API+UI] Switch Dashboard from time-based to commit-based filtering
ldionne Apr 20, 2026
43fb240
Reorganize todos
ldionne Apr 20, 2026
e16fa90
[TEMPORARY] Adjust deployment for my personal account - temporary for…
ldionne Apr 20, 2026
83232b1
Remove stale v5 code from v4 code path
ldionne Apr 20, 2026
4d1bc23
Remove dead "v4 UI" button from v5 navbar
ldionne Apr 20, 2026
18cc888
[Perf] Batch test get-or-create in run submission
ldionne Apr 20, 2026
6386d4d
[Perf] Use Core INSERT for sample creation in run submission
ldionne Apr 20, 2026
9e40b85
[Perf] Add (test_id, run_id) compound index on Sample table
ldionne Apr 20, 2026
5b0d34f
Simplify baseline commit pickers to use server-side machine filtering
ldionne Apr 20, 2026
88f0dba
[Perf] Add response compression via flask-compress
ldionne Apr 20, 2026
08a6a79
[Profiles] Add profile viewer with A/B comparison, API endpoints, and…
ldionne Apr 20, 2026
0c6a062
[DB+API+UI] Add built-in tag column to v5 Commit table
ldionne Apr 21, 2026
54fbfdd
Add multi-knob noise filtering to Compare page
ldionne Apr 21, 2026
4ad53e1
[Compare] Add comparison summary bar and fix unchanged classification
ldionne Apr 21, 2026
d3e843d
Clean up completed items from v5 TODO list
ldionne Apr 21, 2026
bad0454
[Compare] Show display value in commit picker after selection
ldionne Apr 22, 2026
5c749b5
Add 6 new items to v5 TODO list
ldionne Apr 22, 2026
3d72a49
Add TODO items
ldionne Apr 22, 2026
f25a3e0
[UI] Regression Detail: fix double schema fetch, add indicator summar…
ldionne Apr 23, 2026
ef27ed0
Update TODO list: resolve questions, turn others into actionable items
ldionne Apr 23, 2026
ef8f399
[API] Remove unused GET /tests/{name} endpoint
ldionne Apr 23, 2026
385b992
[API] Switch GET /tests to unified ?search= parameter
ldionne Apr 23, 2026
acd8fd7
[UI] Rewrite Graph page with modular architecture
ldionne Apr 23, 2026
8632c66
[API] Fix query pagination: use Sample.id tiebreaker, stop excluding …
ldionne Apr 23, 2026
3e6296b
[UI] Remove dead exports left behind by Graph page rewrite
ldionne Apr 23, 2026
74398d7
[UI] Fix machines search: send ?search= instead of ?name_contains=
ldionne Apr 23, 2026
0f0f8a0
Update TODO list: remove completed items, add audit findings
ldionne Apr 23, 2026
ee7e9c9
[API] Raise max pagination page size from 500 to 10,000
ldionne Apr 23, 2026
48152ef
[UI] Add comprehensive tests for Graph page controls, baselines, and …
ldionne Apr 23, 2026
8d316e4
[UI] Add Computation Reference to Compare design doc, fix noise thres…
ldionne Apr 23, 2026
25ceea5
[UI+API] Unify search and filter: substring matching, re: regex, visu…
ldionne Apr 24, 2026
ef63556
[UI] Compare summary bar: use comparable-only denominator, 1-decimal …
ldionne Apr 26, 2026
13d6e7c
[UI] Fix filter-typing lag on Compare and Graph pages
ldionne Apr 25, 2026
463b582
[UI] Add shadow trace overlay to Compare page chart
ldionne Apr 27, 2026
84144b2
Update TODOs
ldionne Apr 28, 2026
e322dfb
[UI] Show clickable regression link in Compare page feedback
ldionne Apr 28, 2026
ebece4f
[UI] Replace inline regression search with proper combobox component
ldionne Apr 28, 2026
c1f1b44
Add TODO for regressions on Compare page
ldionne Apr 28, 2026
a9dac88
[API+UI] Add has_profiles filter to commits and runs endpoints
ldionne Apr 28, 2026
96254ab
[API+DB] Accept optional client-provided UUID on run submission
ldionne Apr 29, 2026
1cfa1a1
[UI] Add copy-as-CSV button to Compare page
ldionne Apr 30, 2026
cd23550
[UI] Unify combobox components into generic base
ldionne Apr 29, 2026
4cdc32e
[UI] Add commit display values to Profiles page
ldionne Apr 30, 2026
6bb9315
[UI] Fix missing tests section header not updating with filters
ldionne Apr 30, 2026
359deb3
[UI] Fix copy-as-CSV button disappearing on chart zoom
ldionne Apr 30, 2026
d0584e6
[UI] Add sample count tooltips to Compare page table cells
ldionne May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 5 additions & 16 deletions .github/workflows/build-docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,8 @@ jobs:
# Use the current directory as context, as checked out by actions/checkout -- needed for setuptools_scm
context: .

- name: Smoke test - start server and ping it
run: |
docker compose -f docker/compose.yaml up --build --detach
timeout 120 bash -c 'until curl -sf http://localhost:8000; do sleep 2; done'
curl -f http://localhost:8000
env:
LNT_DB_PASSWORD: smoke-test-password
LNT_AUTH_TOKEN: smoke-test-token

- name: Dump logs on failure
if: failure()
run: docker compose -f docker/compose.yaml logs

- name: Teardown
if: always()
run: docker compose -f docker/compose.yaml down
- name: Install tox
run: pip install tox

- name: Smoke test - v5 Docker deployment
run: tox -e docker
6 changes: 6 additions & 0 deletions .github/workflows/tox.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ jobs:
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ matrix.python-version }}
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand All @@ -37,3 +41,5 @@ jobs:
run: tox -e mypy
- name: Tox py3
run: tox -e py3
- name: Tox js
run: tox -e js
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ lnt/server/ui/static/docs
test_run_tmp
tests/**/Output
venv
lnt/server/ui/v5/frontend/node_modules/
lnt/server/ui/v5/static/v5/v5.js
lnt/server/ui/v5/static/v5/v5.js.map
lnt/server/ui/v5/static/v5/v5.css
lnt/server/ui/v5/static/v5/favicon.ico
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ recursive-include docs *
recursive-include tests *
recursive-include examples *
recursive-include lnt/server/ui/static *.css *.js *.html *.ico *.txt
recursive-include lnt/server/ui/v5/static *.css *.js *.map
recursive-include lnt/server/ui/templates *.html
recursive-include lnt/server/db/migrations *
include lnt/server/ui/static/flot/Makefile
Expand Down
4 changes: 2 additions & 2 deletions deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ The Docker Compose service itself should now be running, and it can be inspected

```bash
docker ps
docker logs webserver
docker logs dbserver # usually less interesting
docker compose -f docker/compose.yaml logs webserver
docker compose -f docker/compose.yaml logs db # usually less interesting
```

The database is stored in an independent EBS storage that gets attached and detached
Expand Down
2 changes: 1 addition & 1 deletion deployment/compose.prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
services:
webserver:
build: !reset
image: ghcr.io/llvm/llvm-lnt:${LNT_IMAGE:-latest}
image: ghcr.io/ldionne/llvm-lnt:${LNT_IMAGE:-latest}

volumes:
instance:
Expand Down
4 changes: 2 additions & 2 deletions deployment/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

terraform {
backend "s3" {
bucket = "lnt.llvm.org-terraform-state-prod"
bucket = "lnt.llvm.org-terraform-state-ldionne"
key = "terraform.tfstate"
region = "us-west-2"
encrypt = true
Expand Down Expand Up @@ -37,7 +37,7 @@ data "aws_secretsmanager_secret_version" "lnt_secrets_latest" {

locals {
# The Docker image to use for the webserver part of the LNT service
lnt_image = "56a3c8974301d2c70cc14676bf29974bb623ca6c"
lnt_image = "v5"

# The port on the EC2 instance used by the Docker webserver for communication
lnt_external_port = "80"
Expand Down
10 changes: 6 additions & 4 deletions docker/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#
# Additionally, the following aspects can be customized:
#
# LNT_HOST_PORT
# The host port to expose the webserver on. Defaults to '8000'.
#
# LNT_NGINX_CONFIG
# The path to the configuration file to use for Nginx. By default, './nginx.conf'
# is used, however this must be specified whenever running from a host where the
Expand All @@ -35,13 +38,12 @@ name: llvm-lnt

services:
webserver:
container_name: webserver
build:
context: ../
dockerfile: docker/lnt.dockerfile
environment:
- DB_USER=lntuser
- DB_HOST=dbserver
- DB_HOST=db
- DB_NAME=lnt
- DB_PASSWORD_FILE=/run/secrets/lnt-db-password
- AUTH_TOKEN_FILE=/run/secrets/lnt-auth-token
Expand All @@ -56,12 +58,12 @@ services:
volumes:
- instance:/var/lib/lnt
ports:
- "8000:8000"
- "${LNT_HOST_PORT:-8000}:8000"
networks:
- lnt_network
platform: linux/amd64

db:
container_name: dbserver
image: docker.io/postgres:18-alpine
environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/lnt-db-password
Expand Down
21 changes: 12 additions & 9 deletions docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@ password="$(cat ${DB_PASSWORD_FILE})"
token="$(cat ${AUTH_TOKEN_FILE})"
DB_PATH="postgres://${DB_USER}:${password}@${DB_HOST}"

INSTANCE_DIR=/var/lib/lnt/instance

# Set up the instance the first time this gets run.
if [ ! -e /var/lib/lnt/instance/lnt.cfg ]; then
if [ ! -e "${INSTANCE_DIR}/lnt.cfg" ]; then
lnt-wait-db "${DB_PATH}/${DB_NAME}"
lnt create /var/lib/lnt/instance \
--wsgi lnt_wsgi.py \
--tmp-dir /tmp/lnt \
--db-dir "${DB_PATH}" \
--default-db "${DB_NAME}" \
--api-auth-token "${token}"
lnt create "${INSTANCE_DIR}" \
--wsgi lnt_wsgi.py \
--tmp-dir /tmp/lnt \
--db-dir "${DB_PATH}" \
--default-db "${DB_NAME}" \
--api-auth-token "${token}" \
--db-version 5.0
fi

# Run the server under gunicorn.
cd /var/lib/lnt/instance
cd "${INSTANCE_DIR}"
exec gunicorn lnt_wsgi:application \
--bind 0.0.0.0:8000 \
--workers 8 \
--workers 8 \
--timeout 300 \
--name lnt_server \
--access-logfile - \
Expand Down
21 changes: 21 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ Accessing Data outside of LNT: REST API

LNT provides comprehensive REST APIs to access and manage data stored in the LNT database.

v5 API (Recommended)
--------------------

The v5 API is the latest REST API for LNT. It provides interactive documentation via
Swagger UI, available at::

http://<server>/api/v5/openapi/swagger-ui

The OpenAPI 3.0 specification is also available in JSON format at::

http://<server>/api/v5/openapi/openapi.json

The v5 API uses Bearer token authentication, natural keys (machine names, test names)
instead of internal IDs, cursor-based pagination, and a standardized error format.
Refer to the Swagger UI for the complete list of endpoints and their parameters.

v4 API (Legacy)
---------------

The v4 API is documented below for reference. New integrations should use the v5 API.

Quick Reference
---------------

Expand Down
81 changes: 81 additions & 0 deletions docs/design/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# v5 Design Documentation

This directory contains the design documentation for the LNT v5 project. It is
the authoritative reference for what v5 does and why.

## What is v5?

LNT v5 is a ground-up redesign of the database, REST API, and web UI layers.
Key changes from v4:

- **Database**: PostgreSQL-only, schema-in-DB, the "Commit" concept replaces
"Order" (cleanly separating identity, ordering, and display), no FieldChange
table (regressions use direct indicators).
- **API**: flask-smorest with OpenAPI 3.x, cursor-based pagination, bearer
token auth with scope hierarchy, all JSON responses.
- **UI**: Single-page application in vanilla TypeScript + Vite, client-side
routing, all data from the v5 REST API.

v4 and v5 coexist in the same codebase, selected by `db_version` in `lnt.cfg`
(`'0.4'` for v4, `'5.0'` for v5). They are fully disjoint: a v4 instance
serves only v4 views, and a v5 instance serves only v5 API endpoints and the
v5 frontend.

## Design Principles

- **PostgreSQL only**. No SQLite or MySQL support.
- **SQLAlchemy 1.3** (same version as v4, to avoid upgrade risk).
- **Python 3.10+** idioms: type hints (`X | Y`, `list[T]`), dataclasses,
f-strings, `match` where appropriate.
- **No backward compatibility** with v4 formats or APIs. Clean break.
- **No auto-detection** of regressions. External tools create regressions via
the API.

## Document Map

### Database Layer — [`db/`](db/)

| Document | Contents |
|----------|----------|
| [Data Model](db/data-model.md) | Architecture, Commit concept, schema storage and format, all table definitions |
| [Operations](db/operations.md) | Run submission, commit metadata, search, time-series queries, ordinal management, v4 migration, deferred features |

### REST API — [`api/`](api/)

| Document | Contents |
|----------|----------|
| [Infrastructure](api/infrastructure.md) | Framework (flask-smorest), URL structure, pagination, filtering, response format, authentication, testing, deferred features, AI orientation |
| [Endpoints](api/endpoints.md) | All entity endpoint specifications: machines, commits, runs, tests, samples, profiles, regressions, time series, schema, admin |

### Web UI — [`ui/`](ui/)

| Document | Contents |
|----------|----------|
| [Architecture](ui/architecture.md) | SPA design, client-side routing, Flask backend routes, navigation bar, frontend code structure, build config, implementation phases |
| [Dashboard](ui/dashboard.md) | Landing page with sparkline trend overview across test suites |
| [Browsing Pages](ui/browsing.md) | Test Suites page (suite picker + tabs), Machine Detail, Run Detail, Commit Detail, Regression Detail, and inline regression list/triage |
| [Graph](ui/graph.md) | Time-series visualization: multi-machine, lazy loading, test selection, baselines, regression annotations |
| [Compare](ui/compare.md) | Side-by-side comparison of two commits/runs: selection panel, ratio chart, geomean summary, bidirectional sync |
| [Admin](ui/admin.md) | API key management, test suite schema management |

### Historical Discussion

| Document | Contents |
|----------|----------|
| [Discussion: Orders](v5-discussion-about-orders.md) | Exploration of approaches that led to the Commit concept (design rationale) |


## v4 Features NOT Carried Forward

These v4 pages are intentionally omitted from the v5 UI:

| v4 Feature | Rationale |
|------------|-----------|
| Daily Report | Subsumed by Dashboard + Graph. The dashboard shows sparkline trends; the graph page shows detailed time-series. |
| Latest Runs Report | Subsumed by Dashboard (sparkline trend overview) and Test Suites page (Recent Activity tab). |
| Summary Report | Low usage, "WIP" in v4. Can be added later if needed. |
| Matrix View | Niche use case. The Graph page with per-test drill-down covers the same need. |
| Global Status | Subsumed by Dashboard (sparkline trend overview with per-machine traces). |
| Profile Admin | Operational concern, not a core user workflow. Keep in v4. |
| Submit Run page | Runs are submitted via CLI (`lnt submit`) or API. A form-based UI is rarely used. |
| Rules page | Read-only diagnostic page. Keep in v4 for ops. |
Loading
Loading