.PHONY: help install install-research install-launch install-full repo-hygiene oss-check labels-sync github-launch-audit github-launch-apply release-check \
       sdk-release-check launch-manual-gpu-sync launch-manual-gpu-bootstrap launch-manual-gpu-push launch-manual-gpu-pull launch-manual-gpu-run \
       launch-manual-gpu-preflight launch-manual-gpu-remote-preflight launch-manual-gpu-remote-baseline \
       launch-manual-gpu-remote-reward-calibration launch-manual-gpu-remote-process-reward-fit launch-manual-gpu-remote-proof \
       launch-baseline-check launch-baseline launch-baseline-show launch-reward-calibration \
       launch-reward-calibration-show launch-process-reward-fit \
       launch-process-reward-show launch-proof-prepare launch-proof-prepare-latest launch-proof-review launch-proof-surface-check \
       launch-proof-prepare-best \
       launch-proof-check launch-proof-check-prepared \
       launch-candidate-check \
       launch-proof launch-proof-prepared launch-proof-show launch-browser-smoke launch-browser-smoke-deployed \
       launch-browser-smoke-auth launch-browser-smoke-deployed-auth aws-launch-preflight aws-launch-debug-ssh aws-launch-refresh-ssh aws-launch-dns-targets aws-launch-env aws-launch-create aws-launch-deploy \
       test lint format \
       typecheck coverage build clean docs docs-build docker-up docker-down \
       docker-build benchmark publish \
       test-structured test-async test-tracing test-testgen test-training test-trainable \
       test-websocket test-distributed test-openapi test-migrations test-all openapi \
       db-upgrade db-downgrade db-revision db-current

AEGIS ?= uv run --no-sync aegis
PYTHON ?= $(shell if [ -x .venv/bin/python ]; then printf '%s' .venv/bin/python; else printf '%s' python3; fi)
LAUNCH_BASELINE_CONFIG ?= configs/strict_benchmarks/legal_launch_baseline_template.yaml
LAUNCH_PROOF_CONFIG ?= configs/strict_benchmarks/legal_launch_flagship_template.yaml
LAUNCH_PREPARED_CONFIG ?= artifacts/launch-proof/prepared-launch-proof.yaml
LAUNCH_REWARD_CALIBRATION_EXAMPLES ?=
LAUNCH_REWARD_CALIBRATION_DOMAIN ?= legal
LAUNCH_PROCESS_REWARD_MODEL_NAME ?= legal-launch-prm
LAUNCH_MANUAL_GPU_HOST ?=
LAUNCH_MANUAL_GPU_USER ?= ubuntu
LAUNCH_MANUAL_GPU_KEY_PATH ?= $(HOME)/.ssh/aegis-gpu-training.pem
LAUNCH_MANUAL_GPU_REMOTE_ROOT ?= /opt/aegis/repo
LAUNCH_MANUAL_GPU_REMOTE_TARGET ?=
LAUNCH_PROOF_REVIEW_PROOF_ID ?=
LAUNCH_PROOF_REVIEW_STATUS ?= in_review
LAUNCH_PROOF_REVIEW_SEVERITY ?=
LAUNCH_PROOF_REVIEW_OWNER ?=
LAUNCH_PROOF_REVIEW_SUMMARY ?=
LAUNCH_PROOF_REVIEW_NOTES ?=
LAUNCH_PROOF_REVIEW_TAGS ?=
BASELINE_RUN_ID ?=
REWARD_CALIBRATION_REPORT_ID ?=
RELEASE_TAG ?=
AWS_LAUNCH_NAME ?= aegis-launch-prod
AWS_LAUNCH_ENV_FILE ?= $(HOME)/.aegis/deployments/$(AWS_LAUNCH_NAME).env
AWS_LAUNCH_STATE_FILE ?= $(HOME)/.aegis/deployments/$(AWS_LAUNCH_NAME)-aws.json
SITE_HOST ?= metronis.space
APP_HOST ?= app.metronis.space
API_HOST ?= api.metronis.space
TLS_EMAIL ?= support@metronis.space
BOOTSTRAP_EMAIL ?= support@metronis.space
BOOTSTRAP_NAME ?= Arnav

help:
	@printf '%s\n' \
		'Aegis Make Targets' \
		'' \
		'Setup:' \
		'  make install              Lean operator install for CLI, API, and repo work' \
		'  make install-research     Add eval and dataset tooling for research work' \
		'  make install-launch       Add strict launch-path training and scoring deps' \
		'' \
		'Core checks:' \
		'  make oss-check            Public OSS sanity checks (hygiene, lint, mypy)' \
		'  make test                 Run the full Python test suite' \
		'  make lint                 Run Ruff lint checks' \
		'  make typecheck            Run strict mypy' \
		'  make docs-build           Build docs in strict mode' \
		'' \
		'GitHub and releases:' \
		'  make labels-sync          Sync the checked-in GitHub label taxonomy' \
		'  make github-launch-audit  Audit live GitHub repo settings against launch policy' \
		'  make github-launch-apply  Show the repo-level GitHub settings patch for launch' \
		'  make release-check RELEASE_TAG=vX.Y.Z' \
		'  make sdk-release-check RELEASE_TAG=sdk-vX.Y.Z' \
		'' \
		'AWS launch host:' \
		'  make aws-launch-preflight Non-destructive AWS, DNS, and host readiness audit' \
		'  make aws-launch-debug-ssh Diagnose launch host SSH, console, and recovery access' \
		'  make aws-launch-refresh-ssh Refresh launch SSH access for the current operator IP' \
		'  make aws-launch-dns-targets Print the exact DNS A records required for launch' \
		'  make aws-launch-env       Generate a production env file outside the repo' \
		'  make aws-launch-create    Create or reuse the EC2 launch host and Elastic IP' \
		'  make aws-launch-deploy    Rsync the repo and deploy the public Compose stack' \
		'' \
		'Launch-proof workflow:' \
		'  make launch-manual-gpu-sync      Rsync the repo to the manual GPU worker' \
		'  make launch-manual-gpu-bootstrap Install launch deps on the manual GPU worker' \
		'  make launch-manual-gpu-push      Sync launch working files to the manual GPU worker' \
		'  make launch-manual-gpu-run LAUNCH_MANUAL_GPU_REMOTE_TARGET="make launch-baseline"' \
		'  make launch-manual-gpu-pull      Pull persisted launch artifacts back from the manual GPU worker' \
		'  make launch-manual-gpu-preflight Verify manual GPU worker and strict baseline readiness' \
		'  make launch-manual-gpu-remote-preflight Run the preflight on the manual GPU worker' \
		'  make launch-manual-gpu-remote-baseline  Validate and run the baseline remotely, then pull artifacts' \
		'  make launch-manual-gpu-remote-reward-calibration LAUNCH_REWARD_CALIBRATION_EXAMPLES=...' \
		'  make launch-manual-gpu-remote-process-reward-fit LAUNCH_REWARD_CALIBRATION_EXAMPLES=...' \
		'  make launch-manual-gpu-remote-proof     Validate and run the prepared launch proof remotely, then pull artifacts' \
		'  make launch-proof-review LAUNCH_PROOF_REVIEW_OWNER=... LAUNCH_PROOF_REVIEW_SUMMARY=...' \
		'  make launch-proof-surface-check  Verify homepage, /proof, and release-train proof consistency' \
		'  make launch-candidate-check RELEASE_TAG=vX.Y.Z Run the non-GPU launch candidate trust gate' \
		'  make launch-baseline-check' \
		'  make launch-baseline' \
		'  make launch-reward-calibration LAUNCH_REWARD_CALIBRATION_EXAMPLES=...' \
		'  make launch-proof-prepare-latest' \
		'  make launch-proof-check-prepared' \
		'  make launch-proof-prepared' \
		'' \
		'Day-to-day utilities:' \
		'  make docs                 Serve docs locally' \
		'  make docker-up            Start local infra services' \
		'  make clean                Remove build and cache artifacts'

install:
	$(PYTHON) -m pip install -e ".[dev,operator]"

install-research:
	$(PYTHON) -m pip install -e ".[dev,research]"

install-launch:
	$(PYTHON) -m pip install -e ".[dev,launch]"

install-full:
	$(PYTHON) -m pip install -e ".[dev,all]"

repo-hygiene:
	$(PYTHON) scripts/check_public_repo_hygiene.py
	$(PYTHON) scripts/check_workflow_pins.py

oss-check:
	$(PYTHON) scripts/check_public_repo_hygiene.py
	$(PYTHON) scripts/check_workflow_pins.py
	$(PYTHON) -m ruff check src/ tests/ scripts/
	$(PYTHON) -m mypy src/aegis/

labels-sync:
	$(PYTHON) scripts/sync_github_labels.py

github-launch-audit:
	$(PYTHON) scripts/audit_github_launch_settings.py

github-launch-apply:
	$(PYTHON) scripts/apply_github_launch_settings.py

aws-launch-preflight:
	STACK_NAME="$(AWS_LAUNCH_NAME)" \
	STATE_PATH="$(AWS_LAUNCH_STATE_FILE)" \
	ENV_FILE="$(AWS_LAUNCH_ENV_FILE)" \
	SITE_HOST="$(SITE_HOST)" \
	APP_HOST="$(APP_HOST)" \
	API_HOST="$(API_HOST)" \
	bash infra/aws/public-launch/preflight.sh

aws-launch-debug-ssh:
	STACK_NAME="$(AWS_LAUNCH_NAME)" \
	STATE_PATH="$(AWS_LAUNCH_STATE_FILE)" \
	bash infra/aws/public-launch/debug_ssh.sh

aws-launch-refresh-ssh:
	STACK_NAME="$(AWS_LAUNCH_NAME)" \
	STATE_PATH="$(AWS_LAUNCH_STATE_FILE)" \
	bash infra/aws/public-launch/refresh_ssh_access.sh

aws-launch-dns-targets:
	STACK_NAME="$(AWS_LAUNCH_NAME)" \
	STATE_PATH="$(AWS_LAUNCH_STATE_FILE)" \
	SITE_HOST="$(SITE_HOST)" \
	APP_HOST="$(APP_HOST)" \
	API_HOST="$(API_HOST)" \
	bash infra/aws/public-launch/print_dns_targets.sh

aws-launch-env:
	OUTPUT_PATH="$(AWS_LAUNCH_ENV_FILE)" \
	SITE_HOST="$(SITE_HOST)" \
	APP_HOST="$(APP_HOST)" \
	API_HOST="$(API_HOST)" \
	TLS_EMAIL="$(TLS_EMAIL)" \
	BOOTSTRAP_EMAIL="$(BOOTSTRAP_EMAIL)" \
	BOOTSTRAP_NAME="$(BOOTSTRAP_NAME)" \
	bash infra/aws/public-launch/generate_env.sh

aws-launch-create:
	STACK_NAME="$(AWS_LAUNCH_NAME)" \
	STATE_PATH="$(AWS_LAUNCH_STATE_FILE)" \
	bash infra/aws/public-launch/create_launch_stack.sh

aws-launch-deploy:
	STACK_NAME="$(AWS_LAUNCH_NAME)" \
	STATE_PATH="$(AWS_LAUNCH_STATE_FILE)" \
	ENV_FILE="$(AWS_LAUNCH_ENV_FILE)" \
	bash infra/aws/public-launch/deploy.sh

release-check:
	@if [ -z "$(RELEASE_TAG)" ]; then echo "RELEASE_TAG is required, for example: make release-check RELEASE_TAG=v0.1.0"; exit 1; fi
	$(PYTHON) scripts/check_release_metadata.py --tag "$(RELEASE_TAG)"

sdk-release-check:
	@if [ -z "$(RELEASE_TAG)" ]; then echo "RELEASE_TAG is required, for example: make sdk-release-check RELEASE_TAG=sdk-v0.1.0"; exit 1; fi
	$(PYTHON) scripts/check_release_metadata.py --tag "$(RELEASE_TAG)" --sdk

launch-manual-gpu-preflight:
	bash scripts/run_launch_manual_gpu_preflight.sh "$(LAUNCH_BASELINE_CONFIG)"

launch-manual-gpu-sync:
	@if [ -z "$(LAUNCH_MANUAL_GPU_HOST)" ]; then echo "LAUNCH_MANUAL_GPU_HOST is required, for example: make launch-manual-gpu-sync LAUNCH_MANUAL_GPU_HOST=203.0.113.10"; exit 1; fi
	MODE=sync \
	HOST="$(LAUNCH_MANUAL_GPU_HOST)" \
	REMOTE_USER="$(LAUNCH_MANUAL_GPU_USER)" \
	KEY_PATH="$(LAUNCH_MANUAL_GPU_KEY_PATH)" \
	REMOTE_ROOT="$(LAUNCH_MANUAL_GPU_REMOTE_ROOT)" \
	bash scripts/launch_manual_gpu_worker.sh

launch-manual-gpu-bootstrap:
	@if [ -z "$(LAUNCH_MANUAL_GPU_HOST)" ]; then echo "LAUNCH_MANUAL_GPU_HOST is required, for example: make launch-manual-gpu-bootstrap LAUNCH_MANUAL_GPU_HOST=203.0.113.10"; exit 1; fi
	MODE=bootstrap \
	HOST="$(LAUNCH_MANUAL_GPU_HOST)" \
	REMOTE_USER="$(LAUNCH_MANUAL_GPU_USER)" \
	KEY_PATH="$(LAUNCH_MANUAL_GPU_KEY_PATH)" \
	REMOTE_ROOT="$(LAUNCH_MANUAL_GPU_REMOTE_ROOT)" \
	bash scripts/launch_manual_gpu_worker.sh

launch-manual-gpu-push:
	@if [ -z "$(LAUNCH_MANUAL_GPU_HOST)" ]; then echo "LAUNCH_MANUAL_GPU_HOST is required, for example: make launch-manual-gpu-push LAUNCH_MANUAL_GPU_HOST=203.0.113.10"; exit 1; fi
	MODE=push-launch-files \
	HOST="$(LAUNCH_MANUAL_GPU_HOST)" \
	REMOTE_USER="$(LAUNCH_MANUAL_GPU_USER)" \
	KEY_PATH="$(LAUNCH_MANUAL_GPU_KEY_PATH)" \
	REMOTE_ROOT="$(LAUNCH_MANUAL_GPU_REMOTE_ROOT)" \
	bash scripts/launch_manual_gpu_worker.sh

launch-manual-gpu-pull:
	@if [ -z "$(LAUNCH_MANUAL_GPU_HOST)" ]; then echo "LAUNCH_MANUAL_GPU_HOST is required, for example: make launch-manual-gpu-pull LAUNCH_MANUAL_GPU_HOST=203.0.113.10"; exit 1; fi
	MODE=pull-launch-artifacts \
	HOST="$(LAUNCH_MANUAL_GPU_HOST)" \
	REMOTE_USER="$(LAUNCH_MANUAL_GPU_USER)" \
	KEY_PATH="$(LAUNCH_MANUAL_GPU_KEY_PATH)" \
	REMOTE_ROOT="$(LAUNCH_MANUAL_GPU_REMOTE_ROOT)" \
	bash scripts/launch_manual_gpu_worker.sh

launch-manual-gpu-run:
	@if [ -z "$(LAUNCH_MANUAL_GPU_HOST)" ]; then echo "LAUNCH_MANUAL_GPU_HOST is required, for example: make launch-manual-gpu-run LAUNCH_MANUAL_GPU_HOST=203.0.113.10 LAUNCH_MANUAL_GPU_REMOTE_TARGET='make launch-baseline'"; exit 1; fi
	@if [ -z "$(LAUNCH_MANUAL_GPU_REMOTE_TARGET)" ]; then echo "LAUNCH_MANUAL_GPU_REMOTE_TARGET is required, for example: make launch-manual-gpu-run LAUNCH_MANUAL_GPU_HOST=203.0.113.10 LAUNCH_MANUAL_GPU_REMOTE_TARGET='make launch-baseline'"; exit 1; fi
	MODE=run \
	HOST="$(LAUNCH_MANUAL_GPU_HOST)" \
	REMOTE_USER="$(LAUNCH_MANUAL_GPU_USER)" \
	KEY_PATH="$(LAUNCH_MANUAL_GPU_KEY_PATH)" \
	REMOTE_ROOT="$(LAUNCH_MANUAL_GPU_REMOTE_ROOT)" \
	REMOTE_COMMAND="$(LAUNCH_MANUAL_GPU_REMOTE_TARGET)" \
	bash scripts/launch_manual_gpu_worker.sh

launch-baseline-check:
	$(AEGIS) pipeline strict-benchmark-config --config $(LAUNCH_BASELINE_CONFIG) --check-only

launch-baseline:
	mkdir -p artifacts/launch-proof
	$(AEGIS) pipeline strict-benchmark-config --config $(LAUNCH_BASELINE_CONFIG) --output artifacts/launch-proof/latest-baseline.json

launch-baseline-show:
	$(AEGIS) pipeline strict-benchmark-show --latest

launch-reward-calibration:
	@if [ -z "$(LAUNCH_REWARD_CALIBRATION_EXAMPLES)" ]; then echo "LAUNCH_REWARD_CALIBRATION_EXAMPLES is required. Copy configs/strict_benchmarks/legal_reward_calibration_examples.template.json, replace the placeholders with real expert-aligned examples, and rerun."; exit 1; fi
	mkdir -p artifacts/launch-proof
	$(AEGIS) train calibrate-reward --examples $(LAUNCH_REWARD_CALIBRATION_EXAMPLES) --domain $(LAUNCH_REWARD_CALIBRATION_DOMAIN) --strict --artifacts-root artifacts --output artifacts/launch-proof/latest-reward-calibration.json

launch-reward-calibration-show:
	$(AEGIS) train calibrate-reward-show --latest --artifacts-root artifacts

launch-process-reward-fit:
	@if [ -z "$(LAUNCH_REWARD_CALIBRATION_EXAMPLES)" ]; then echo "LAUNCH_REWARD_CALIBRATION_EXAMPLES is required. Reuse the real expert-aligned reward calibration examples before fitting a verifier."; exit 1; fi
	mkdir -p artifacts/launch-proof
	$(AEGIS) train fit-process-reward-model --examples $(LAUNCH_REWARD_CALIBRATION_EXAMPLES) --domain $(LAUNCH_REWARD_CALIBRATION_DOMAIN) --strict --model-name $(LAUNCH_PROCESS_REWARD_MODEL_NAME) --artifacts-root artifacts --output artifacts/launch-proof/latest-process-reward-fit.json

launch-process-reward-show:
	$(AEGIS) train fit-process-reward-model-show --latest --artifacts-root artifacts

launch-proof-prepare:
	@if [ -z "$(BASELINE_RUN_ID)" ]; then echo "BASELINE_RUN_ID is required. Run make launch-baseline, then use make launch-baseline-show to capture the persisted strict benchmark run id."; exit 1; fi
	@if [ -z "$(REWARD_CALIBRATION_REPORT_ID)" ]; then echo "REWARD_CALIBRATION_REPORT_ID is required. Run make launch-reward-calibration with real expert-aligned examples and reuse the persisted report id."; exit 1; fi
	mkdir -p artifacts/launch-proof
	$(AEGIS) pipeline launch-proof-prepare --config $(LAUNCH_PROOF_CONFIG) --output $(LAUNCH_PREPARED_CONFIG) --baseline-run-id $(BASELINE_RUN_ID) --reward-calibration-report-id $(REWARD_CALIBRATION_REPORT_ID)

launch-proof-prepare-latest:
	mkdir -p artifacts/launch-proof
	$(AEGIS) pipeline launch-proof-prepare --config $(LAUNCH_PROOF_CONFIG) --output $(LAUNCH_PREPARED_CONFIG) --latest-baseline --latest-reward-calibration --artifacts-root artifacts

launch-proof-prepare-best:
	mkdir -p artifacts/launch-proof
	$(AEGIS) pipeline launch-proof-prepare --config $(LAUNCH_PROOF_CONFIG) --output $(LAUNCH_PREPARED_CONFIG) --latest-baseline --latest-reward-calibration --latest-process-reward-model --artifacts-root artifacts

launch-proof-check:
	$(AEGIS) pipeline launch-proof --config $(LAUNCH_PROOF_CONFIG) --check-only

launch-proof-check-prepared:
	@if [ ! -f "$(LAUNCH_PREPARED_CONFIG)" ]; then echo "$(LAUNCH_PREPARED_CONFIG) was not found. Run make launch-proof-prepare with real BASELINE_RUN_ID and REWARD_CALIBRATION_REPORT_ID first."; exit 1; fi
	$(AEGIS) pipeline launch-proof --config $(LAUNCH_PREPARED_CONFIG) --check-only

launch-proof:
	mkdir -p artifacts/launch-proof
	$(AEGIS) pipeline launch-proof --config $(LAUNCH_PROOF_CONFIG) --output artifacts/launch-proof/latest.json

launch-proof-prepared:
	@if [ ! -f "$(LAUNCH_PREPARED_CONFIG)" ]; then echo "$(LAUNCH_PREPARED_CONFIG) was not found. Run make launch-proof-prepare with real BASELINE_RUN_ID and REWARD_CALIBRATION_REPORT_ID first."; exit 1; fi
	mkdir -p artifacts/launch-proof
	$(AEGIS) pipeline launch-proof --config $(LAUNCH_PREPARED_CONFIG) --output artifacts/launch-proof/latest.json

launch-proof-show:
	$(AEGIS) pipeline launch-proof-show --latest

launch-proof-review:
	@if [ -z "$(LAUNCH_PROOF_REVIEW_OWNER)" ]; then echo "LAUNCH_PROOF_REVIEW_OWNER is required, for example: make launch-proof-review LAUNCH_PROOF_REVIEW_OWNER='launch-ops' LAUNCH_PROOF_REVIEW_SUMMARY='Approved for launch candidate review.'"; exit 1; fi
	@if [ -z "$(LAUNCH_PROOF_REVIEW_SUMMARY)" ]; then echo "LAUNCH_PROOF_REVIEW_SUMMARY is required, for example: make launch-proof-review LAUNCH_PROOF_REVIEW_OWNER='launch-ops' LAUNCH_PROOF_REVIEW_SUMMARY='Approved for launch candidate review.'"; exit 1; fi
	$(AEGIS) pipeline launch-proof-review $(if $(LAUNCH_PROOF_REVIEW_PROOF_ID),--proof-id "$(LAUNCH_PROOF_REVIEW_PROOF_ID)",--latest) --status "$(LAUNCH_PROOF_REVIEW_STATUS)" $(if $(LAUNCH_PROOF_REVIEW_SEVERITY),--severity "$(LAUNCH_PROOF_REVIEW_SEVERITY)",) --owner "$(LAUNCH_PROOF_REVIEW_OWNER)" --summary "$(LAUNCH_PROOF_REVIEW_SUMMARY)" --notes "$(LAUNCH_PROOF_REVIEW_NOTES)" --tags "$(LAUNCH_PROOF_REVIEW_TAGS)" --artifacts-root artifacts

launch-proof-surface-check:
	$(AEGIS) pipeline launch-proof-surface-check --latest --artifacts-root artifacts --site-url "https://$(SITE_HOST)" --api-url "https://$(API_HOST)"

launch-candidate-check:
	$(AEGIS) pipeline launch-candidate-check $(if $(RELEASE_TAG),--release-tag "$(RELEASE_TAG)",) --artifacts-root artifacts --site-url "https://$(SITE_HOST)" --app-url "https://$(APP_HOST)" --api-url "https://$(API_HOST)"

launch-manual-gpu-remote-preflight:
	$(MAKE) launch-manual-gpu-run LAUNCH_MANUAL_GPU_REMOTE_TARGET="make launch-manual-gpu-preflight"

launch-manual-gpu-remote-baseline:
	$(MAKE) launch-manual-gpu-run LAUNCH_MANUAL_GPU_REMOTE_TARGET="make launch-baseline-check"
	$(MAKE) launch-manual-gpu-run LAUNCH_MANUAL_GPU_REMOTE_TARGET="make launch-baseline"
	$(MAKE) launch-manual-gpu-pull

launch-manual-gpu-remote-reward-calibration:
	@if [ -z "$(LAUNCH_REWARD_CALIBRATION_EXAMPLES)" ]; then echo "LAUNCH_REWARD_CALIBRATION_EXAMPLES is required. Copy configs/strict_benchmarks/legal_reward_calibration_examples.template.json, replace the placeholders with real expert-aligned examples, and rerun."; exit 1; fi
	$(MAKE) launch-manual-gpu-push
	$(MAKE) launch-manual-gpu-run LAUNCH_MANUAL_GPU_REMOTE_TARGET="make launch-reward-calibration LAUNCH_REWARD_CALIBRATION_EXAMPLES=$(LAUNCH_REWARD_CALIBRATION_EXAMPLES) LAUNCH_REWARD_CALIBRATION_DOMAIN=$(LAUNCH_REWARD_CALIBRATION_DOMAIN)"
	$(MAKE) launch-manual-gpu-pull

launch-manual-gpu-remote-process-reward-fit:
	@if [ -z "$(LAUNCH_REWARD_CALIBRATION_EXAMPLES)" ]; then echo "LAUNCH_REWARD_CALIBRATION_EXAMPLES is required. Reuse the real expert-aligned reward calibration examples before fitting a verifier."; exit 1; fi
	$(MAKE) launch-manual-gpu-push
	$(MAKE) launch-manual-gpu-run LAUNCH_MANUAL_GPU_REMOTE_TARGET="make launch-process-reward-fit LAUNCH_REWARD_CALIBRATION_EXAMPLES=$(LAUNCH_REWARD_CALIBRATION_EXAMPLES) LAUNCH_REWARD_CALIBRATION_DOMAIN=$(LAUNCH_REWARD_CALIBRATION_DOMAIN) LAUNCH_PROCESS_REWARD_MODEL_NAME=$(LAUNCH_PROCESS_REWARD_MODEL_NAME)"
	$(MAKE) launch-manual-gpu-pull

launch-manual-gpu-remote-proof:
	@if [ ! -f "$(LAUNCH_PREPARED_CONFIG)" ]; then echo "$(LAUNCH_PREPARED_CONFIG) was not found. Run make launch-proof-prepare-latest, make launch-proof-prepare-best, or make launch-proof-prepare with real persisted evidence first."; exit 1; fi
	$(MAKE) launch-manual-gpu-push
	$(MAKE) launch-manual-gpu-run LAUNCH_MANUAL_GPU_REMOTE_TARGET="make launch-proof-check-prepared"
	$(MAKE) launch-manual-gpu-run LAUNCH_MANUAL_GPU_REMOTE_TARGET="make launch-proof-prepared"
	$(MAKE) launch-manual-gpu-pull

launch-browser-smoke:
	npm run test:e2e

launch-browser-smoke-deployed:
	npm run test:e2e:deployed

launch-browser-smoke-auth:
	npm run test:e2e:auth

launch-browser-smoke-deployed-auth:
	npm run test:e2e:deployed:auth

test:
	$(PYTHON) -m pytest tests/ -v

lint:
	$(PYTHON) -m ruff check src/ tests/ scripts/

format:
	$(PYTHON) -m ruff format src/ tests/ scripts/

typecheck:
	$(PYTHON) -m mypy src/aegis/

coverage:
	$(PYTHON) -m pytest tests/ --cov=aegis --cov-report=term-missing --cov-fail-under=80

build:
	$(PYTHON) -m build

docs:
	$(PYTHON) -m mkdocs serve

docs-build:
	$(PYTHON) -m mkdocs build --strict

docker-build:
	docker compose build

docker-up:
	docker compose up -d

docker-down:
	docker compose down

benchmark:
	mkdir -p benchmarks/results
	$(AEGIS) eval benchmark --suite legal-heldout --output benchmarks/results/legal-heldout-latest.json
	$(AEGIS) eval benchmark --suite cuad-heldout --output benchmarks/results/cuad-heldout-latest.json
	$(AEGIS) eval benchmark --suite legalbench-heldout --output benchmarks/results/legalbench-heldout-latest.json
	$(AEGIS) eval benchmark --suite financebench-train-proxy --output benchmarks/results/financebench-train-proxy-latest.json

publish: build
	$(PYTHON) -m twine upload dist/*

test-structured:
	$(PYTHON) -m pytest tests/test_structured_output.py tests/test_retry_policies.py tests/test_llm_cache.py -v

test-async:
	$(PYTHON) -m pytest tests/test_decomposed_metrics.py tests/test_async_eval.py -v

test-tracing:
	$(PYTHON) -m pytest tests/test_otel_tracing.py -v

test-testgen:
	$(PYTHON) -m pytest tests/test_testgen.py tests/test_sandbox.py -v

test-training:
	$(PYTHON) -m pytest tests/test_distributed_training.py tests/test_verl_bridge.py -v

test-trainable:
	$(PYTHON) -m pytest tests/test_trainable_metrics.py -v

test-websocket:
	$(PYTHON) -m pytest tests/test_websocket.py -v

test-distributed:
	$(PYTHON) -m pytest tests/test_distributed_training.py -v

test-openapi:
	$(PYTHON) -m pytest tests/test_openapi_spec.py -v

openapi:
	$(PYTHON) scripts/export_openapi.py

db-upgrade:
	$(AEGIS) db upgrade head

db-downgrade:
	$(AEGIS) db downgrade -1

db-revision:
	aegis db revision -m "$(MSG)"

db-current:
	$(AEGIS) db current

test-migrations:
	$(PYTHON) -m pytest tests/test_migrations.py -v

sdk-generate:
	bash scripts/generate_sdk.sh

sdk-build:
	cd sdk/typescript && npm run build

sdk-test:
	cd sdk/typescript && npm test

test-dashboard:
	cd apps/dashboard && npm test

test-all: test test-structured test-async test-tracing test-testgen test-websocket test-trainable test-migrations

clean:
	rm -rf dist/ build/ *.egg-info src/*.egg-info .coverage htmlcov/ .mypy_cache/ .pytest_cache/ .ruff_cache/ site/
	find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
