Status: active Document type: operational-guide Owner: developer experience Canonical scope: operations.getting-started Read when: installing Performance Lab or running the local browser product Last reviewed: 2026-09-01
This is the shortest supported path from a clean checkout to the current local browser product. dev is the canonical integration branch; main is release-oriented and is promoted deliberately after FULL validation.
Performance Lab uses one locked local toolchain:
uv 0.12.5for Python installation, dependency locking, the repository.venv, command execution and builds;- Python
3.12as the default local line from.python-version; - Node
24.18.0fromfrontend/.nvmrc; - pnpm
11.24.0fromfrontend/package.json#packageManager; uv.lockandfrontend/pnpm-lock.yamlas the only dependency lockfiles.
Install uv and a Node version manager/Corepack before continuing. Do not create a second virtual environment and do not use pip install -e, npm or an alternate lockfile for repository setup.
git clone https://github.com/daniele21/performance-lab.git
cd performance-lab
git checkout dev
git pull --ff-only origin devIf the repository is already cloned:
git fetch origin
git checkout dev
git pull --ff-only origin devFrom the repository root:
uv python install 3.12
uv sync --extra dev --locked
corepack enable
corepack install --global pnpm@11.24.0
pnpm --dir frontend install --frozen-lockfile
pnpm --dir frontend exec playwright install chromiumuv sync creates and owns .venv. You do not need to activate it: canonical Python commands use uv run --extra dev --locked ..., which executes against the locked repository environment.
Verify the toolchain and environment:
uv run --extra dev --locked python scripts/doctor.pyThe doctor should report the repository .venv, uv.lock, Node, pnpm and frontend/pnpm-lock.yaml as OK.
The reference adapter expects an OpenAI-compatible endpoint with at least:
GET /v1/models
POST /v1/chat/completions
Probe the endpoint before running the UI:
uv run --extra dev --locked performance-lab probe \
--base-url http://127.0.0.1:1235/v1/ \
--model my-modelA healthy probe confirms the minimum inference path, not optional streaming, token-usage or runtime-identity capabilities.
Save this as local-run.json and replace the endpoint/model values with the service you are testing:
{
"schema_version": 1,
"target_id": "local-model",
"endpoint_identity": "127.0.0.1:1235",
"endpoint": {
"profile_id": "local-endpoint",
"base_url": "http://127.0.0.1:1235/v1/",
"model_selector": "my-model"
},
"model_id": "my-model",
"store_path": ".performance-lab/runs.sqlite3"
}For Local LLM Server, add the optional first-party identity and telemetry blocks described in local-llm-server-integration.md. The inference base URL includes /v1/; identity/status use the server root.
Build the same frontend artifact used by the assembled product:
pnpm --dir frontend run buildServe the built frontend and Performance Lab API from one loopback-owned process:
uv run --extra dev --locked performance-lab-ui \
--config local-run.json \
--assets frontend/distOpen:
http://127.0.0.1:8765
Use this mode for product/UX review because it exercises the built frontend with the real local API composition instead of the Vite development server.
Stop it with Ctrl-C. The process owns only the loopback listener; model serving remains external.
Use two terminals when actively changing the frontend.
Terminal 1 — Performance Lab API:
uv run --extra dev --locked performance-lab-ui \
--config local-run.json \
--port 8765Terminal 2 — Vite:
pnpm --dir frontend run devOpen:
http://127.0.0.1:5173
Vite binds to loopback and proxies /api to http://127.0.0.1:8765. Both development servers use strict ports and fail on collision instead of silently choosing another port.
Canonical repository checks are defined in .engineering/commands.json. The common local gates are:
uv run --extra dev --locked python scripts/validate.py
pnpm --dir frontend run check
pnpm --dir frontend run test
pnpm --dir frontend run buildComplete deterministic product E2E:
uv run --extra dev --locked python -m pytest tests/e2e -v --tb=shortPRE_REAL browser evidence:
uv run --extra dev --locked python scripts/pre_real_e2e.py \
--output-root build/pre-real-e2eThese fixture/hosted environments do not prove real model/device performance; representative runtime/device evidence remains a separate RUNTIME-1 requirement.
A single evaluation can be started directly from the same config:
uv run --extra dev --locked performance-lab run --config local-run.jsonThe run is persisted in SQLite and exported as a portable .plab.zip evidence bundle. Use --json for machine-readable output.
To compare a baseline and candidate after two completed compatible runs:
uv run --extra dev --locked performance-lab regress \
--store .performance-lab/runs.sqlite3 \
--baseline-run <baseline-run-id> \
--candidate-run <candidate-run-id> \
--policy regression-policy.jsonCompatibility is evaluated before thresholds or deltas.
Python dependency changes update pyproject.toml and uv.lock together. Frontend dependency changes update frontend/package.json and frontend/pnpm-lock.yaml together.
Do not hand-edit lockfiles and do not introduce a parallel requirements constraints file, package-lock.json or another package-manager path. Toolchain/dependency changes require the repository's FULL validation profile.
For configuration details see run-config-reference.md. For evidence outputs see output-and-evidence-reference.md. For failures see troubleshooting.md.