# Project export: VASCTRACE AI

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: VascuTrace AI is a physics-informed PET/CT research copilot that measures when subtle vascular FDG abnormalities become detectable using healthy PET/CT data, AI, and quantitative analysis.
- Devpost: https://devpost.com/software/vasctrace-ai
- GitHub: https://github.com/venkat1596/VascuTrace_AI
- Video: https://www.youtube.com/embed/G_y25jNryvQ?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 3 GitHub contributor(s) — venkat (4 commits), Claude Opus 4.8 (2 commits), pbiyyani09 (2 commits)

## Devpost submission (written by the team)

### Inspiration

Medical imaging research has a chicken-and-egg problem: you cannot train or fairly evaluate a detector for a rare vascular finding without labeled examples, but the labeled examples barely exist. So we flipped the question. Instead of chasing scarce disease labels, we asked a bounded, honestly-answerable one: Under controlled image-domain conditions, when can a compact PET/CT model localize a simulated vascular-like FDG source in a healthy scan, and what can deterministic code actually measure about it? VascuTrace is our answer — a reproducible method-development prototype, not a diagnostic system. It is a research prototype trained and evaluated on simulated vascular-like sources, and no result here establishes clinical sensitivity, specificity, or patient benefit. The second inspiration was about how rigorous research gets built. We wanted to see whether an AI agent could own the parts of research that usually bottleneck a small team — planning, architecture, scientific review, and report writing — while keeping a hard line: generated language must never be able to change a measured number. That "Work, Life and Productivity" angle — using Codex and GPT-5.6 as a disciplined research engine — is as much the project as the model is.

### What it does

VascuTrace is an end-to-end PET/CT research pipeline on the public QUADRA healthy test/retest cohort (Zenodo 16686025: 48 subjects, 96 sessions, 960 NIfTI files): Physical-coordinate geometry — PET and CT live on different grids, so every multimodal op uses patient RAS coordinates and named transforms, never matching array indices. Controlled synthetic-source engine — inserts a parameterized vascular-like FDG source (radius, uptake multiplier, blur) into raw SUV, giving ground truth by construction. A 2.5-D shared-weight Siamese U-Net ("B2", deep supervision) that reads five adjacent PET and CT slices per bilateral branch and emits an uncalibrated abnormality_score map. Deterministic 3-D quantification that returns SUV statistics — or structured nulls with explicit QC reasons, never silent zeros. A product layer with an auditable tool trace, an executable evaluation suite, and a verifier that rejects any generated report whose numbers or claims drift. On a freshly rebuilt, leakage-verified held-out validation cache (90 positive slices), the trained model reproduced the reported behavior: We report the misses too — the honest spread matters more than one aggregate.

### How we built it

The division of labor was deliberate: Codex, powered by GPT-5.6 (gpt-5.6-sol), owned every non-coding role: planning and architecture, primary technical decisions, scientific and critical review, report writing, and Git/release handling. It converted the research goal into bounded plans with explicit acceptance checks. Claude implemented code only from those Codex-authored plans. The team kept final authority over every scientific, licensing, and submission decision. The sanitized public receipt covers 11 Codex sessions on GPT-5.6 — 5,654 tool calls, 654 code patches, 629 bounded reviews, over 28,000 structured source records and 123.76 observed hours. The core engineering principle is that measurement code is physically separate from generated prose. Numbers come from pure, side-effect-free functions; the language model may write interpretation, but a deterministic verifier compares every reported value against the source within tolerance and rejects prohibited claims. For example, laterality asymmetry is a fixed formula, not a model opinion: \( \text{asymmetry_index} = \dfrac{\bar{S}{\text{target}} - \bar{S}{\text{contra}}}{\bar{S}_{\text{contra}} + \varepsilon} \) and physical volume comes straight from the affine determinant, never a hardcoded spacing: $$ V_{\text{mL}} = \frac{N_{\text{vox}} \,\lvert \det(A_{3\times3}) \rvert}{1000}. $$ Stack: Python 3.13, PyTorch + MONAI, NumPy/SciPy, nibabel/SimpleITK, Streamlit, Pydantic, the Model Context Protocol, uv/ruff/pytest — 735 offline tests pass deterministically on CPU with no data or weights required.

### Challenges we ran into

A 14 GB memory wall. Cropping one whole-body session peaked at ~14 GB and OOM-killed our machine, blocking the entire real-data path. The culprit was the RAS canonicalization: an exact signed-permutation remap that was materializing dense whole-volume float64 coordinate grids. We replaced it with a transpose + per-axis flip — provably bit-identical (verified against the old path) — cutting the peak to ~3.6 GB and unblocking everything. A data-leakage trap. The dataset split uses seed 20260713, but the training seed is 20260716. Naively reusing the training seed would have put training subjects into the "held-out" evaluation. We caught it and verified every evaluated subject was genuinely held out. Honest reproduction, not cherry-picking. Our independently rebuilt cache lands close to the reported numbers but not identical — and we show exactly why (a 15-vs-13-bundle cache and a known legacy-reflection gap) rather than papering over it. Keeping the scientific boundary intact end-to-end — every artifact carries the "simulated, not clinical" warning, and invalid measurements stay as structured nulls.

### What we learned

Determinism is a feature, not a constraint. Making measurement code incapable of being rewritten by an LLM — rather than merely instructing it not to — is what makes the pipeline trustworthy. AI can own the research scaffolding. Codex/GPT-5.6 tracing requirements, catching a statistical defect, and assembling an evidence-classed report genuinely accelerated the work — while a human kept final authority. Read the seeds. In imaging ML, a one-line seed mismatch is the difference between a held-out result and accidental leakage. Efficiency is correctness-adjacent. A ~14× memory blow-up hid inside an "obviously cheap" axis permutation.

### What's next

The report is explicit about what would be needed before any promotion claim: native-space 3-D mask stitching, 26-connected component matching, a subject-clustered bootstrap on a sealed test split, a promotion-compliant threshold baseline, and wiring the standalone 3-D quantifier into the product path. Until then, VascuTrace is what it says it is: a disciplined, reproducible research prototype on simulated sources — not a diagnosis.

## README (from the GitHub repository)

# VascuTrace AI

> Research prototype. Trained and evaluated using simulated vascular-like abnormalities, not confirmed human post-angioplasty lesions.

VascuTrace is a reproducible PET/CT method-development prototype. It studies
whether controlled vascular-like synthetic sources can be detected and
quantified in healthy PET/CT backgrounds. It is not a diagnostic system and no
reported result establishes clinical sensitivity, clinical specificity, or
patient benefit.

The detailed technical report is available at
[docs/report/VascuTrace_Technical_Report_2026-07-20.pdf](docs/report/VascuTrace_Technical_Report_2026-07-20.pdf).
It includes aggregate EDA, method schematics, actual generated product views,
the verified five-tool runtime trace, all six product checks, corrected
development-collaboration evidence, and a sanitized analysis of 11 root Codex
sessions. No patient image or model weight is used in the report evidence
build.

## Current implementation

The repository contains:

* PET/CT geometry utilities that use physical patient coordinates and named
  transforms
* subject-grouped data contracts and deterministic bilateral crop generation
* a parameterized image-domain synthetic-source engine
* a transparent threshold baseline
* deterministic 3D quantification with structured null and QC results
* a 2.5D shared-weight Siamese U-Net training and evaluation path
* a research-demonstrator application with deterministic tools, MCP exposure,
  optional local evidence retrieval, report generation, and numeric-fidelity
  verification

The product workflow keeps measurement code separate from generated prose.
Language generation cannot create or replace quantitative values. The default
report backend is a deterministic template, and the default detection backend
is a synthetic-reference path intended for integration testing. The trained
Siamese backend is opt-in and currently processes a selected cached 2D
validation sample rather than a complete scan.

The current exploratory B2 result was measured on 208 validation center slices,
including 78 positive and 130 negative slices, drawn from seven subject
clusters. At the frozen operating point, positive-slice mean IoU was 0.614895,
75 of 78 positive slices had a target-overlapping prediction, and 37 of 130
negative slices contained activation. These are validation-only 2D observations,
not held-out test, scan-level, 3D, or clinical performance estimates.

## Setup

The project targets Python 3.13 and uses
[uv](https://docs.astral.sh/uv/) for dependency management.

```bash
uv sync --locked
uv run ruff check --no-cache .
uv run ruff format --check --no-cache .
uv run pytest -q -m "not local_data and not gpu" \
  -k "not test_dataloader_with_multiple_workers"
```

CPU and offline tests use generated fixtures. Dataset files, medical volumes,
model weights, caches, credentials, and run outputs are not versioned.

The multiprocessing DataLoader node is verified separately because restricted
containers may not allow worker processes to complete. During release review,
it reached a 90-second cap without pytest failure output. On a host that permits
multiprocessing, run:

```bash
uv run pytest -q \
  tests/test_ml_dataset.py::TestPicklingAndDataLoader::test_dataloader_with_multiple_workers
```

## Research demonstrator

Run the deterministic local dashboard:

```bash
uv run streamlit run app.py
```

Run the product evaluation and complete synthetic case paths:

```bash
uv run python -m scripts.run_product_evaluation
uv run python -m scripts.run_complete_case
```

Rebuild the generated-only product receipt and report figures 09 through 11:

```bash
uv run python docs/report/scripts/build_product_evidence.py
```

Run the MCP server over standard input and output:

```bash
uv run python -m vascutrace.mcp_server
```

Generated artifacts are written under the configured output root and remain
untracked.

## Optional product backends

Every optional backend is explicitly selected. Offline deterministic behavior
is the default.

| Setting | Default | Optional value |
|:--|:--|:--|
| `VASCUTRACE_DETECTION_BACKEND` | `reference` | `siamese` |
| `VASCUTRACE_REPORT_BACKEND` | `template` | `llm` |
| `VASCUTRACE_EVIDENCE_BACKEND` | `keyword` | `rag` |

The optional report path uses an OpenAI reasoning model for interpretation and
local Qwen models for embedding and reranking. Deterministic code owns all
measurements and laterality fields. The public retrieval corpus must be rebuilt
locally before enabling RAG because generated indices are not versioned.

## Collaboration with Codex

Codex with GPT-5.6 performed every non-coding workflow role in the VascuTrace
development process. This included planning and architecture, primary technical
decisions, scientific review, report writing, delivery review, Git and release
handling, and humanizer and editorial review. Codex also authored the plans and
instructions used for code implementation. Claude was used only to implement
that planned code. The project owner retained final authority over all product,
scientific, publication, licensing, repository, category, video, and submission
decisions.

The public evidence projection covers 11 root Codex sessions through
`2026-07-21T14:56:53.784Z`. Their metadata records `gpt-5.6-sol` in all 11
sessions. The projection contains 87 user turns, 725 assistant updates, 69
started tasks, 60 completed tasks, 5,654 tool-call events, 654 patch events,
629 bounded review activities, 77 web searches, and 38 context compactions.
These are structural event counts, not measures of quality, labor time, or
scientific performance.

VascuTrace product GenAI prompts are shipped application code. Private
development-agent artifacts are excluded from the public release. The
[session-based collaboration record](docs/CODEX_COLLABORATION.md) documents the
public decision and evidence trail, links the sanitized
[session receipt](docs/report/evidence/codex_session_evidence.json), and shows
the collaboration, timeline, and activity figures. The
[hackathon submission guide](docs/HACKATHON_SUBMISSION.md) collects the
description, demonstration, testing, and owner-completed submission fields.
The selected competition category is `Work, Life and Productivity`.

## Scientific status and limitations

The implemented components are not yet a fully integrated scientific pipeline.
Important open work includes:

* replacing the legacy bilateral-reflection crop method with the frozen
  iliac-only physical-coordinate method
* completing a promotion-compliant threshold baseline
* stitching model outputs into native-space 3D masks
* running subject-clustered evaluation on a sealed test split
* integrating the standalone 3D quantifier into the product path
* rebuilding and reevaluating the sanitized public retrieval corpus

Invalid or unavailable scientific measurements should be represented as
structured nulls with explicit QC reasons, never silently converted to zeros.

## Branches

* `main` is the release branch.
* `dev` is the active development branch.

CI runs lockfile, lint, formatting, and test checks for pushes and pull requests.


## Detected evidence (automated analysis)

Indexed codebase: 114 recognized source files, 1805 KB.
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- PyTorch (technology) — detected in the code
- Streamlit (technology) — detected in the code
- AI coding agent: Claude Code — evidence: commit authorship or trailers

## Codebase structure (from repository index)

### Files (120 of 124)

```
.github/workflows/ci.yml
.gitignore
.python-version
app.py
configs/train_siamese_b3_softdml.yaml
configs/train_siamese_p3_A.yaml
configs/train_siamese_p3_B.yaml
configs/train_siamese_p3_C.yaml
configs/train_siamese_p4b1_aug.yaml
configs/train_siamese_p4b1_fair_seed2.yaml
configs/train_siamese_p4b1_fair.yaml
configs/train_siamese_p4b1c_scale15.yaml
configs/train_siamese_p4b2_deepsup_seed2.yaml
configs/train_siamese_p4b2_deepsup.yaml
configs/train_siamese_p4l3_dice.yaml
configs/train_siamese_p4l3b_0p6_0p4.yaml
configs/train_siamese_v1.yaml
configs/train_siamese_v2.yaml
configs/train_siamese_v3.yaml
configs/train_siamese_v4_big.yaml
configs/train_siamese_v5exp.yaml
configs/train_siamese_v6exp.yaml
configs/train_siamese_v7b_seed2.yaml
configs/train_siamese_v7b.yaml
configs/train_siamese_v7soft.yaml
dashboard/__init__.py
dashboard/components.py
dashboard/theme.py
docs/CODEX_COLLABORATION.md
docs/HACKATHON_SUBMISSION.md
docs/report/evidence/aggregate_evidence.json
docs/report/evidence/codex_session_evidence.json
docs/report/evidence/product_demo_receipt.json
docs/report/references.bib
docs/report/scripts/build_codex_session_evidence.py
docs/report/scripts/build_product_evidence.py
docs/report/scripts/build_report_figures.py
docs/report/VascuTrace_Technical_Report_2026-07-20.tex
knowledge/research_corpus.json
plans/VascuTrace_Publication_and_Reproducibility_Plan_2026-07-20.md
pyproject.toml
README.md
scripts/__init__.py
scripts/b2_ensemble_eval.py
scripts/b3_grad_balance_probe.py
scripts/build_rag_index.py
scripts/eda_quadra.py
scripts/fp_cnr_gate_probe.py
scripts/fp_component_autopsy.py
scripts/p3_lambda_probe.py
scripts/rag_eval.py
scripts/run_complete_case.py
scripts/run_p2_pipeline.py
scripts/run_product_evaluation.py
src/vascutrace/__init__.py
src/vascutrace/baselines/__init__.py
src/vascutrace/baselines/threshold.py
src/vascutrace/data/__init__.py
src/vascutrace/data/contract.py
src/vascutrace/data/crops.py
src/vascutrace/data/ingest.py
src/vascutrace/data/split.py
src/vascutrace/genai/__init__.py
src/vascutrace/genai/llm.py
src/vascutrace/genai/rag.py
src/vascutrace/genai/report_agent.py
src/vascutrace/geometry.py
src/vascutrace/ml/__init__.py
src/vascutrace/ml/cache.py
src/vascutrace/ml/checkpoint.py
src/vascutrace/ml/cli.py
src/vascutrace/ml/dataset.py
src/vascutrace/ml/evaluate.py
src/vascutrace/ml/infer.py
src/vascutrace/ml/losses.py
src/vascutrace/ml/metrics.py
src/vascutrace/ml/model.py
src/vascutrace/ml/tensor_schema.py
src/vascutrace/ml/train.py
src/vascutrace/quantification/__init__.py
src/vascutrace/quantification/measure.py
src/vascutrace/simulation/__init__.py
src/vascutrace/simulation/anomaly.py
tests/conftest.py
tests/test_baselines.py
tests/test_codex_session_evidence.py
tests/test_contracts_and_verifier.py
tests/test_data_pipeline.py
tests/test_evaluation.py
tests/test_evidence.py
tests/test_experiments_and_pipeline.py
tests/test_first_checkpoint.py
tests/test_genai_layer.py
tests/test_geometry.py
tests/test_mcp_server.py
tests/test_ml_aug_b1_invariants.py
tests/test_ml_b3_soft_term.py
tests/test_ml_boundary_aux.py
tests/test_ml_configs.py
tests/test_ml_dataset.py
tests/test_ml_deep_supervision.py
tests/test_ml_evaluate.py
tests/test_ml_infer.py
tests/test_ml_metrics.py
tests/test_ml_model.py
tests/test_ml_train.py
tests/test_ml_tversky_rebalance.py
tests/test_operating_point_knobs.py
tests/test_product_backends.py
tests/test_quantification.py
tests/test_simulation.py
tests/test_smoke.py
uv.lock
vascutrace/__init__.py
vascutrace/contracts.py
vascutrace/evaluation.py
vascutrace/evidence.py
vascutrace/experiments.py
vascutrace/mcp_server.py
vascutrace/orchestrator.py
[4 more files omitted for size]
```

### Dependencies

- pyproject.toml: matplotlib@>=3.11.0, mcp[cli]@>=1.28.1, monai@==1.5.1, nibabel@>=5.4.2, numpy@>=2.5.1, openai@>=2.46.0, openpyxl@>=3.1.5, pandas@>=3.0.3, pillow@>=12.3.0, pyarrow@>=25.0.0, pydantic@>=2.13.4, pyyaml@>=6.0.3, scikit-image@>=0.26.0, scikit-learn@>=1.9.0, scipy@>=1.18.0, seaborn@>=0.13.2, sentence-transformers@>=5.6.0, simpleitk@>=2.5.5, statsmodels@>=0.14.6, streamlit@>=1.48.0, torch@==2.9.1, tqdm@>=4.68.4

### Recent commits (newest first)

- Merge pull request #1 from venkat1596/merge-dev-into-main
- Merge dev into main: release full VascuTrace pipeline
- perf(geometry): O(1)-memory RAS canonicalization via transpose/flip
- release: publish report and Codex evidence
- Clarify documented Codex collaboration
- Publish VascuTrace prototype, report, and Codex collaboration record
- Initial commit: project scaffold, uv env, CI

## Key source files (fetched from GitHub, selected and truncated for size)

### plans/VascuTrace_Publication_and_Reproducibility_Plan_2026-07-20.md

```markdown
# VascuTrace publication and reproducibility plan

Date: 2026-07-20

> Research prototype. Trained and evaluated using simulated vascular-like abnormalities, not confirmed human post-angioplasty lesions.

## Purpose

This plan defines the public path from the current research prototype to a reproducible methods package. It covers the technical report, aggregate evidence, code verification, scientific acceptance gates, sanitized Codex session evidence, and a development-branch release. It contains no private development configuration, prompt, raw transcript, hidden reasoning, raw session file, or model weight.

## Publication package

The release package should contain:

1. The installable VascuTrace source and product orchestration code.
2. Generated-fixture tests, CPU and offline regression tests, and clearly marked optional data or GPU tests.
3. Public configuration files required to reproduce model architecture and intended training settings.
4. The technical report source, bibliography, machine-readable aggregate evidence ledger, generated-only product receipt, sanitized Codex session receipt, three figure builders, thirteen publication figures, and compiled PDF.
5. Public algorithm notes and this project-facing plan.
6. A README that distinguishes the deterministic reference fixture from the optional learned backend.

The release must not contain medical volumes, identifiers, per-case tables, model weights, run outputs, credentials, caches, local retrieval indices, or workstation-specific material.

## Frozen scientific language

Public artifacts use `abnormality_score` for an uncalibrated model output. They describe target-overlapping predictions on synthetic inputs and activation on negative healthy-control backgrounds. They do not report clinical diagnosis, clinical sensitivity or specificity, arterial-wall truth, scanner sensitivity, patient-motion or attenuation-correction simulation, treatment response, or outcomes.

The exact research warning appears in the report, application, structured reports, and relevant documentation.

## Evidence model

Each report result belongs to one class:

- Primary-source fact, with a direct citation.
- Historical aggregate measurement, with an input hash and an explicit note that it was not rerun during publication.
- Current implementation observation, tied to reviewed code.
- Design decision, stated as a rule rather than a result.
- Planned evaluation, stated in future tense.
- Sanitized development-process evidence, tied to a fixed session cutoff and a
  field-limited public receipt.

The aggregate evidence ledger records the population, independent unit, value, units, status, source hash, and limitation for every public number used in a figure.

The session receipt records 11 root sessions through
`2026-07-21T14:56:53.784Z`. All eleven record model identifier `gpt-5.6-sol`.
The aggregate structural counts are 87 user turns, 725 assistant updates, 69
started tasks, 60 completed tasks, 5,654 tool call
[truncated — 10000 more characters]
```

### docs/CODEX_COLLABORATION.md

```markdown
# Codex collaboration and session evidence

> Research prototype. Trained and evaluated using simulated vascular-like abnormalities, not confirmed human post-angioplasty lesions.

This public record documents how Codex with GPT-5.6 supported VascuTrace and
connects that work to reviewable repository artifacts. It combines a role and
decision chronology with a sanitized projection of 11 root Codex sessions. The
selected hackathon category is `Work, Life and Productivity`.

Codex with GPT-5.6 performed every non-coding workflow role in the development
process. It owned planning and architecture, primary technical decisions,
scientific review, report writing, delivery review, Git and release handling,
and humanizer and editorial review. Codex also authored the plans and
instructions used for code implementation. Claude implemented code only,
following those instructions. The project owner retained final authority over
product, engineering,
scientific, publication, licensing, repository, category, video, and submission
decisions.

![Development collaboration evidence showing Codex with GPT-5.6 as the owner of every non-coding workflow role, Claude as coding-only implementation, and the project owner as final authority](report/figures/11_collaboration_evidence.png)

*Figure 11, evidence class `DEMO-001`. Codex with GPT-5.6 performed planning,
primary technical decisions, scientific review, report writing, delivery
review, Git and release handling, and humanizer and editorial review. Claude
implemented code only from Codex-authored plans and instructions. The owner
retained final authority. The figure summarizes public outcomes and is separate
from the VascuTrace product runtime.*

## Evidence classes

The collaboration evidence uses two separate classes:

* `DEMO-001` binds the generated product receipt, product views, verified
  runtime output, and the corrected public role summary in Figure 11.
* `SESSION-001` binds the sanitized Codex session receipt, the 11-session
  timeline in Figure 12, and the structural activity counts in Figure 13.

Neither class is detector, clinical, or scientific-performance evidence.
VascuTrace runtime agents and product GenAI prompts are shipped application
code. They are not the development workflow documented here.

## Chronological role and decision record

### 1. Research scope and claim boundary

Codex converted the approved product goal into a bounded method-development
question about image-domain synthetic-source detectability and deterministic
quantification in healthy PET/CT backgrounds. Codex carried the permanent
warning, nonclinical vocabulary, and evidence classes into plans, reviews, the
application, and the technical report. The owner approved the research scope
and retained the final scientific decision.

### 2. Architecture and execution planning

Codex translated the research scope into staged work for physical-coordinate
PET/CT geometry, bilateral crops, controlled synthetic-source generation, a
trans
[truncated — 11402 more characters]
```

### pyproject.toml

```
[project]
name = "vascutrace-ai"
version = "0.1.0"
description = "VascuTrace_AI"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "mcp[cli]>=1.28.1",
    "matplotlib>=3.11.0",
    "monai==1.5.1",
    "nibabel>=5.4.2",
    "numpy>=2.5.1",
    "openpyxl>=3.1.5",
    "pandas>=3.0.3",
    "pillow>=12.3.0",
    "pyarrow>=25.0.0",
    "pydantic>=2.13.4",
    "pyyaml>=6.0.3",
    "scikit-image>=0.26.0",
    "scikit-learn>=1.9.0",
    "scipy>=1.18.0",
    "seaborn>=0.13.2",
    "simpleitk>=2.5.5",
    "statsmodels>=0.14.6",
    "torch==2.9.1",
    "tqdm>=4.68.4",
    "streamlit>=1.48.0",
    "openai>=2.46.0",
    "sentence-transformers>=5.6.0",
]

[dependency-groups]
dev = [
    "hypothesis>=6.156.6",
    "pytest>=8.0",
    "pytest-cov>=7.1.0",
    "ruff>=0.14",
]

[tool.uv]
package = false

[tool.uv.sources]
torch = { index = "pytorch-cu128" }

[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true

[tool.pytest.ini_options]
pythonpath = ["."]
testpaths = ["tests"]
addopts = "--strict-markers"
markers = [
    "local_data: test requires local Data/ access (excluded from CPU/offline CI)",
    "gpu: test requires a CUDA GPU (excluded from CPU/offline CI)",
]

[tool.ruff]
target-version = "py313"
exclude = [".venv"]

```

### app.py

```python
"""VascuTrace AI synthetic research workspace."""

import os

import streamlit as st

from dashboard.components import (
    evidence_card,
    hero,
    metric_card,
    report_text,
    safety_banner,
    section,
    status_row,
    trace_steps,
)
from dashboard.theme import apply_theme
from vascutrace.evaluation import run_evaluation_suite
from vascutrace.orchestrator import (
    run_evidence_request,
    run_experiment_request,
    run_first_checkpoint,
)
from vascutrace.tools import create_overlay


def _format_measurement(value: float | None, digits: int = 3) -> str:
    return "Unavailable" if value is None else f"{value:.{digits}f}"


apply_theme()

with st.spinner("Preparing deterministic research workspace…"):
    result = run_first_checkpoint()
    payload = result.payload
    output = payload["model_output"]
    metrics = payload["metrics"]
    report = payload["report"]
    quality = report["quality_control"]
    views = create_overlay(payload["case"]["case_dir"])


with st.sidebar:
    st.markdown(
        '<div class="vt-brand">VascuTrace<span class="vt-brand-dot"> AI</span></div>',
        unsafe_allow_html=True,
    )
    st.caption("RESEARCH WORKSPACE · v0.1")
    st.divider()
    st.markdown("**Workspace**")
    st.markdown("Overview  ")
    st.markdown("Imaging workspace  ")
    st.markdown("Research report  ")
    st.markdown("Evidence library  ")
    st.markdown("Experiments & audit")
    st.divider()
    st.markdown("**Active case**")
    st.caption(payload["case"]["case_id"])
    st.markdown("**Laterality**")
    st.caption(output["laterality"].title())
    st.markdown("**Abnormality score**")
    st.progress(output["abnormality_score"])
    st.caption(f"{output['abnormality_score']:.3f} uncalibrated research-model output")
    st.divider()
    st.markdown("**Active backends**")
    _active_backends = (
        (
            "Detection",
            "VASCUTRACE_DETECTION_BACKEND",
            "reference",
            {
                "reference": "Deterministic reference",
                "siamese": "Siamese B2 (trained)",
            },
        ),
        (
            "Reasoning report",
            "VASCUTRACE_REPORT_BACKEND",
            "template",
            {
                "template": "Deterministic template",
                "llm": "gpt-5-mini (grounded)",
            },
        ),
        (
            "Evidence",
            "VASCUTRACE_EVIDENCE_BACKEND",
            "keyword",
            {
                "keyword": "Keyword store",
                "rag": "Qwen RAG (embed + rerank)",
            },
        ),
    )
    for _label, _env, _default, _labels in _active_backends:
        _key = os.environ.get(_env, _default)
        st.caption(f"{_label}: {_labels.get(_key, _key)}")
    st.divider()
    st.caption("Synthetic data · Auditable trace · No patient information")

safety_banner()
hero(
    payload["case"]["case_id"],
    payload["verification"]["accepted"],
    output["model_name"],
)

section(
    "Case overview",
    "Quantitative signal at a glance",
    "Deterministic measurements calculated from the active synthetic PET/CT case.",
)
metric_columns = st.columns(4)
metric_specs = (
    (
        "Target SUVmax",
        _format_measurement(metrics["target_suvmax"]),
        "SUV",
        "Target corridor peak",
    ),
    (
        "Contralateral SUVmax",
        _format_measurement(metrics["contralateral_suvmax"]),
        "SUV",
        "Mirrored control peak",
    ),
    (
        "Asymmetry index",
        _format_measurement(metrics["asymmetry_index"]),
        "",
        "Target-to-control difference",
    ),
    (
        "Metabolic volume",
        _format_measurement(metrics["metabolic_volume_ml"]),
        "mL",
        "Simulated target volume",
    ),
)
for column, spec in zip(metric_columns, metric_specs, strict=True):
    with column:
        metric_card(*spec)

section(
    "Multimodal review",
    "Imaging workspace",
    "Move between aligned modalities, segmentation context, and bilateral comparison.",
)
image_column, qc_column = st.columns([2.45, 1], gap="large")
with image_column:
    pet_tab, ct_tab, fusion_tab, overlay_tab, bilateral_tab = st.tabs(
        ["PET", "CT", "Fused", "Mask overlay", "Bilateral"]
    )
    image_tabs = (
        (pet_tab, "pet_path", "Synthetic PET reference · axial slice"),
        (ct_tab, "ct_path", "Synthetic CT anatomy reference · axial slice"),
        (fusion_tab, "fused_path", "PET/CT research fusion · aligned reference"),
        (overlay_tab, "overlay_path", "Target mask in red · simulated ground truth"),
        (
            bilateral_tab,
            "bilateral_path",
            "Mirrored left control ↔ right target comparison",
        ),
    )
    for tab, view_key, caption in image_tabs:
        with tab:
            st.image(views[view_key], caption=caption, width="stretch")

with qc_column:
    st.markdown("### Quality control")
    st.caption("Automated checks attached to this deterministic reference.")
    status_row("Partial-volume effects", quality["partial_volume_risk"])
    status_row("PET/CT misregistration", quality["misregistration_risk"])
    st.markdown("#### Review flags")
    if quality["flags"]:
        for flag in quality["flags"]:
            st.warning(flag.replace("_", " ").title(), icon="⚠️")
    else:
        st.success("No quality-control flags", icon="✅")
    st.markdown("#### Model context")
    st.caption(f"{output['model_name']} · version {output['model_version']}")
    st.caption(f"Runtime {output['runtime_seconds']:.3f} seconds")

section(
    "Verified output",
    "Structured research report",
    "Human-readable interpretation with exact source measurements and safety checks.",
)
report_column, finding_column = st.columns([1.65, 1], gap="large")
with report_column:
    if payload["verification"]["accepted"]:
        st.success("Deterministic verification passed", icon="✅")
    else:
        st.error("Report verification failed", icon="⚠️"
[truncated — 4447 more characters]
```

### src/vascutrace/ml/cli.py

```python
"""Thin argparse CLI for the P6 training loop: ``doctor`` / ``dry-run`` /
``train`` / ``resume``.

RESEARCH_PROTOTYPE_WARNING
---------------------------------------------------------------------------
Research prototype. Trained and evaluated using simulated vascular-like
abnormalities, not confirmed human post-angioplasty lesions.
---------------------------------------------------------------------------

This module intentionally contains no training-loop logic of its own --
every subcommand parses arguments/config, resolves bundle directories, and
delegates to :mod:`src.vascutrace.ml.train` (:func:`~src.vascutrace.ml.
train.train` / :func:`~src.vascutrace.ml.train.resume`). See ``train.py``
and ``checkpoint.py`` for the algorithmic/design rationale. Run via
``uv run python -m src.vascutrace.ml.cli <command> ...``.
"""

from __future__ import annotations

import argparse
import json
import logging
import sys
from collections.abc import Sequence
from pathlib import Path
from typing import Any

import numpy as np
import torch
import yaml

from src.vascutrace.data.contract import (
    CROP_SCHEMA_VERSION,
    FIXED_CROP_SHAPE,
    ILIAC_LABEL_LEFT,
    ILIAC_LABEL_RIGHT,
    make_crop_bundle,
    save_crop_bundle,
)
from src.vascutrace.data.crops import build_reflection_affine
from src.vascutrace.data.split import (
    SPLIT_SEED,
    load_subject_sex_table,
    load_subject_split,
)
from src.vascutrace.data.split import (
    stratified_subject_split as _stratified_subject_split,
)
from src.vascutrace.geometry import RESEARCH_PROTOTYPE_WARNING, GeometrySidecar
from src.vascutrace.ml.cache import CachePrepError, precompute_synthetic_cache
from src.vascutrace.ml.checkpoint import CHECKPOINT_SCHEMA_VERSION, load_checkpoint
from src.vascutrace.ml.dataset import DatasetConfig
from src.vascutrace.ml.model import ModelConfig
from src.vascutrace.ml.tensor_schema import TENSOR_SCHEMA_VERSION
from src.vascutrace.ml.train import (
    CheckpointCompatibilityError,
    CudaOutOfMemoryError,
    CudaUnavailableError,
    NonFiniteLossError,
    TrainConfig,
    TrainConfigError,
    discover_bundle_dirs,
    resume as resume_run,
    train as train_run,
)

__all__ = ["build_parser", "main"]

_DEFAULT_DATA_ROOT = Path("data/processed/p2/crops/p2-crop-v2")

_TRAIN_CONFIG_SPECIAL_KEYS = {
    "data_root",
    "split_path",
    "train_bundle_dirs",
    "val_bundle_dirs",
    "model_config",
    "dataset_config",
    "run_root",
}


# ---------------------------------------------------------------------------
# Config-file -> TrainConfig
# ---------------------------------------------------------------------------


def _load_config_file(path: Path) -> dict[str, Any]:
    path = Path(path)
    text = path.read_text()
    if path.suffix.lower() in (".yaml", ".yml"):
        payload = yaml.safe_load(text)
    else:
        payload = json.loads(text)
    if not isinstance(payload, dict):
        raise TrainConfigError(f"config file {path} must contain a mapping/object")
    return payload


def _model_config_from_dict(payload: dict[str, Any]) -> ModelConfig:
    payload = dict(payload)
    if "channel_mult" in payload:
        payload["channel_mult"] = tuple(payload["channel_mult"])
    return ModelConfig(**payload)


def _dataset_config_from_dict(payload: dict[str, Any]) -> DatasetConfig:
    payload = dict(payload)
    for key in ("radius_mm_range", "uptake_multiplier_range", "blur_fwhm_mm_range"):
        if key in payload:
            payload[key] = tuple(payload[key])
    return DatasetConfig(**payload)


def _bundle_dirs_for_subjects(
    data_root: Path, subjects: Sequence[str]
) -> tuple[Path, ...]:
    wanted = set(subjects)
    return tuple(d for d in discover_bundle_dirs(data_root) if d.parent.name in wanted)


def _resolve_bundle_dirs(
    payload: dict[str, Any],
) -> tuple[tuple[Path, ...], tuple[Path, ...]]:
    """Either an explicit ``train_bundle_dirs``/``val_bundle_dirs`` pair, or
    ``data_root`` + ``split_path`` (a :func:`~src.vascutrace.data.split.
    save_subject_split` JSON file) resolved to bundle directories via
    :func:`~src.vascutrace.ml.train.discover_bundle_dirs`. A cache-only
    config (``train_cache_dir``/``val_cache_dir`` set, no on-the-fly
    bundle-dir source given) resolves to two empty tuples -- valid per
    ``TrainConfig.__post_init__``'s cache-mode relaxation.
    """
    if "train_bundle_dirs" in payload or "val_bundle_dirs" in payload:
        train_dirs = tuple(Path(p) for p in payload.get("train_bundle_dirs", []))
        val_dirs = tuple(Path(p) for p in payload.get("val_bundle_dirs", []))
        return train_dirs, val_dirs

    if "split_path" not in payload:
        if "train_cache_dir" in payload and "val_cache_dir" in payload:
            return (), ()
        raise TrainConfigError(
            "config must supply either explicit train_bundle_dirs/"
            "val_bundle_dirs, data_root + split_path, or "
            "train_cache_dir + val_cache_dir (cache-only mode)"
        )
    data_root = Path(payload.get("data_root", _DEFAULT_DATA_ROOT))
    split = load_subject_split(Path(payload["split_path"]))
    train_dirs = _bundle_dirs_for_subjects(data_root, split.train)
    val_dirs = _bundle_dirs_for_subjects(data_root, split.val)
    return train_dirs, val_dirs


def _train_config_from_dict(payload: dict[str, Any], *, run_root: Path) -> TrainConfig:
    train_dirs, val_dirs = _resolve_bundle_dirs(payload)
    model_cfg = _model_config_from_dict(payload.get("model_config", {}))
    dataset_cfg = _dataset_config_from_dict(payload.get("dataset_config", {}))
    extra = {
        key: value
        for key, value in payload.items()
        if key not in _TRAIN_CONFIG_SPECIAL_KEYS
    }
    return TrainConfig(
        train_bundle_dirs=train_dirs,
        val_bundle_dirs=val_dirs,
        run_root=run_root,
        model_config=model_cfg,
        dataset_config=dataset_cfg,
        **extra,
    )


# ----------------------------------------------------
[truncated — 14435 more characters]
```

### scripts/__init__.py

```python
"""Repository maintenance and validation scripts."""

```

### vascutrace/__init__.py

```python
"""VascuTrace AI deterministic application services."""

```

### dashboard/__init__.py

```python
"""Presentation helpers for the VascuTrace research dashboard."""

```

### tests/conftest.py

```python
"""Test configuration for the repository's non-package uv layout."""

import sys
from pathlib import Path


sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

```

### tests/test_smoke.py

```python
"""Smoke test — proves the environment CI builds is the one we expect.

Replace/extend as VascuTrace_AI grows real modules; this exists so the CI gate
into main is live from the first commit rather than vacuously green.
"""

import sys


def test_python_is_3_13() -> None:
    assert sys.version_info[:2] == (3, 13)

```

[100 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]