# Canonical US76 implementation verification method

Established 8 September 2026. This document is the authoritative procedure for
building `verification.html`. The generator, report and packaging must conform
to it. Update this document when the user changes the verification requirements.

## Purpose and required update workflow

Verify the executed reference implementation against independently published
US76 model data, then verify each implemented language port against that
reference. This is implementation verification, not validation against measured
atmospheric observations. Do not label agreement as a pass without an explicitly
specified acceptance tolerance.

Rebuild verification documentation only during a checkpoint operation, and only
when relevant US76 changes have occurred since the last verified checkpoint.
Relevant changes include formulas, constants, units, altitude handling, reference
code, language ports, shared numerical dependencies, runners, registration,
sampling, report rendering and plotting dependencies.

During implementation work, read this method, make and check the authorized
changes, and record verification as pending in the task/checkpoint notes. Do not
regenerate the report, rewrite this method or repackage verification artifacts
after each edit. Continue numerical/code checks appropriate to the change. The
existing report describes the last generated results, not pending changes.

At a checkpoint, inspect changes since the last verified checkpoint and retained
dependency fingerprints. If there are no relevant changes, skip regeneration.
Otherwise complete the following workflow:

1. Read this document and review the pending changes. Preserve the frozen NASA inputs
   unless the user explicitly requests a source update.
2. Confirm each new port is registered with its actual runner
   and complete dependency fingerprints. Never substitute copied formulas or
   cached outputs from another implementation for execution of that port.
3. Run the report generator using the persistent environment described below.
   Reuse unaffected caches; allow changed dependencies to refresh their results.
   A runtime upgrade requires `--refresh-calculations`.
4. Review both comparison sections and reported differences. Investigate new
   discrepancies; do not adjust source data or hide differences to obtain parity.
5. Run `node webapp/tools/prepare-release.mjs` from the repository root to update
   the app copy and its offline resource hashes. Keep the NASA PDF excluded.
6. Perform checks appropriate to the change: numerical checks for algorithm
   changes, cache tests for caching changes, and browser checks for presentation
   or offline packaging changes. Confirm 14 charts for the seven properties and
   two comparison sections, no data tables, correct labels, working scale
   controls, mobile/desktop layout, and working local links. With new ports,
   retain seven charts per section and add overlays to each port chart.
7. Retain updated canonical report, calculation records, comparisons, chart
   caches and packaged artifacts together. Report what was rebuilt, reused and
   checked. If a required runtime or check is unavailable, report that limitation
   rather than presenting a stale report as rebuilt. Clear the pending status and
   record the verified checkpoint only after successful completion. Do not deploy
   automatically.

A US76 change in the web application's separate implementation also marks
verification pending for the next checkpoint. Run that implementation's existing
numerical comparison checks as appropriate during development and at checkpoint.
The reusable-library report alone does not establish parity of the separate
web application implementation; do not imply it is a registered overlay.

## Frozen independent source

Use the joint NASA/NOAA/USAF *U.S. Standard Atmosphere, 1976*, October 1976,
NASA-TM-X-74335 / NOAA-S/T-76-1562, NASA NTRS record 19770009539.

- Original record: https://ntrs.nasa.gov/citations/19770009539
- External PDF: https://ntrs.nasa.gov/api/citations/19770009539/downloads/19770009539.pdf
- Local research original: `19770009539.pdf`; extracted input: `source_data.csv`.
- Retrieval and CSV extraction: 8 September 2026. Preserve the published precision
  and CSV header attribution, URLs, source page references and source hashes.
- Table I: printed odd pages 53–67; Table III: printed odd pages 101–115.
  Use geometric-altitude rows, not geopotential-altitude rows as the input grid.
- The 85 published rows span 0 to 84,000 m geometric altitude inclusive at 1,000 m.
  They are independent published model data, not outputs synthesized from our code.

Keep source CSV and PDF unchanged during ordinary rebuilds. Source refresh needs
an explicit user request; elapsed time or an implementation change is not one.

## Required presentation

Use **US76 implementation verification** as the main report heading.

Start with a quick link titled **Theoretic Background** to
https://en.wikipedia.org/wiki/U.S._Standard_Atmosphere. Include a **Verification
data** section with source description, edition, publication date, extraction
date, report assembly time and one external link labeled **Original NASA source**
to https://ntrs.nasa.gov/citations/19770009539. Do not include a separate NASA
report/PDF link in the HTML; it is redundant with the source record. Keep actual calculation
timestamps distinct from report assembly time.

Use **AtmostropicRef** as the reference legend label, without `(Dart)` appended.
Explain once in the report that this label denotes the executed Dart reference.
The reference is always a blue `#0072B2` curve. First compare it against NASA
orange `#D55E00` open circles. Follow with all implemented language ports as
open scatter markers against the same reference curve. Use distinct sensible
color/shape combinations; JavaScript uses orange open squares.

Each chart has a title, labeled axes including units, and a sensible grid. Use
geometric altitude (m) on the x axis. Plot all seven shared outputs:

- Temperature (K).
- Pressure (mbar), converting calculated Pa by dividing by 100.
- Density (kg/m³).
- Speed of sound (m/s).
- Dynamic viscosity (N·s/m²), numerically equal to Pa·s.
- Kinematic viscosity (m²/s).
- Geopotential altitude (m).

Do not plot geometric input altitude against itself. Pressure, density and
kinematic viscosity default to logarithmic y axes with a linear-scale option;
other properties use linear axes. Include maximum absolute and relative
difference captions and their altitudes. Relative differences use the comparison
reference as denominator; zero-reference relative differences are undefined.

Do not include data tables, including summary tables, in the HTML. Retain
per-point records in the cache. An opt-in table view or export is a future idea,
not an enabled feature. The report must be legible in full on mobile and desktop.
Embed all chart variants and required styling/scripts so plots work offline.

Open `verification.html` directly. It contains all plots and difference captions,
works offline, and adapts to mobile and desktop screens.

The first seven charts compare the executed Dart reference (`AtmostropicRef`,
blue curve) with the frozen NASA data (orange open circles). The next seven
compare the included registered ports with Dart. JavaScript uses orange open
squares. Partial reports explicitly identify registered ports not included.

NASA comparisons use 85 source altitudes at 1 km intervals. Curves and port
comparison statistics use 841 computed altitudes at 100 m intervals; scatter
overlays use the 85 source altitudes for legibility. Differences in the first
section are Dart minus NASA; differences in the second are port minus Dart.
These sampled comparisons do not establish behavior between samples or outside
0–84 km, and do not test invalid-input handling.

### Explicit partial language coverage

At the user's request on 9 September 2026, a report checkpoint may include only
ports executable on the current machine. Keep all implemented ports registered.
Select the available IDs with `--ports js java csharp python typescript` and
provide `--omission-reason "Local toolchains unavailable; execution remains pending."`.
The default still attempts every registered port; runtime/calculation failures
must not silently omit a selected port. List all omitted languages and the reason
visibly in the language section and retain them in `cache/comparisons.json`.
Do not plot omitted ports from stale caches or mark their verification complete.
Package only the calculation records identified by the report's retained port
signatures. Retain seven charts per section and reuse unaffected NASA plots.

## Regenerate

Use the persistent repository-root `.venv`, shared by all algorithm reports.
See [one-time environment setup](../../../../VERIFICATION.md).
From the repository root in PowerShell:

```powershell
.\.venv\Scripts\python.exe reusable_algorithms/us76_atmosphere/verification_and_validation/verification/generate_verification.py --dart /path/to/dart --node /path/to/node
```

On macOS/Linux, use `.venv/bin/python`. Omit runtime options when they are on
PATH. The script resolves its inputs relative to itself. `DART` and `NODE` environment variables are also
supported. Use the Dart SDK executable directly where practical (on Windows,
Flutter's `bin/cache/dart-sdk/bin/dart.exe`). `--python` selects the interpreter
for future Python runners. No atmosphere formulas are copied into the runners.

A fully cached run needs only Python's standard library: it does not launch
Dart or Node, import Matplotlib, or require internet access. If calculations
have changed, their runtime is needed. If plots need rendering, the shared
environment provides Matplotlib. Keep that installation between runs.

The HTML itself never needs those dependencies. Current SVGs were rendered with
Matplotlib 3.11.1. Intentional changes to the root pinned requirements refresh
the chart cache automatically; numerical caches remain reusable.

## Retained cache and update behavior

- `cache/source.json`: parsed NASA rows and the original CSV/PDF hashes. Neither
  file is downloaded or changed by generation. A source-file hash change stops
  generation. Use `--refresh-source` only after the user explicitly authorizes
  an update to NASA source data. Do not use this flag for ordinary code changes.
- `cache/dart.json`, `cache/js.json`: full-precision raw output rows, actual
  calculation timestamps, dependency hashes, grid, command, and data checksum.
  Each implementation has an independent cache. Changes to its library files,
  runner, command, output schema or altitude grid recompute only that cache.
- `cache/comparisons.json`: retained per-point differences, relative differences,
  RMSE, maximum differences and their altitudes for both comparison sections.
- `cache/plots/` and `cache/plots.json`: SVGs and fingerprints of the renderer, pinned plotting requirements,
  values, property, scales, markers and layout. Only changed plots are rendered.
  A Dart change refreshes affected comparisons in both sections; a port change
  affects only that port's numerical cache and the relevant port charts.
  Identical numerical output can reuse existing plots after a code change.

Keep the cache with the report. Content hashes detect changes even if file
timestamps are preserved. Missing or corrupt numerical/plot cache entries are
rebuilt. Writes of JSON caches are atomic; a failed calculation does not replace
its previous cache or generate a misleading completed report. Run one generator
at a time. The report distinguishes calculation timestamps from assembly time.

Runtime/SDK upgrades are not library-source changes: use
`--refresh-calculations` to force a fresh execution after upgrading a runtime.
Changing the output protocol requires incrementing `SCHEMA` in
`verification_cache.py`. Presentation changes can reuse the numerical caches.

## Add a language port

1. Put the implementation in its `languages/<language>` directory.
2. Add a small runner here that imports that implementation, reads a JSON array
   of geometric altitudes (m) from stdin, and writes one JSON array of results
   to stdout. Each row contains `z` and the eight result keys returned by the
   Dart reference, in the same units. Keep logging off stdout.
3. Add an entry to `implementations.json` under `ports`, with a unique `id`,
   user-facing `label`, `directory`, argument-array `command`, `dependencies`,
   `color`, and `marker`. Commands support `{dart}`, `{node}`, and `{python}`.
   All other paths are relative to this report directory.
4. Include the entire language directory, runner and every external/shared
   library source or dependency manifest in `dependencies`. Paths can name files
   or directories; directories are recursively hashed. Runtime-generated caches
   (`__pycache__`, `.dart_tool`, `node_modules`, `.venv`) are excluded. For an
   external installed library, fingerprint its lockfile and explicitly refresh
   calculations if its installed version changes independently of that lockfile.

For a Python runner, a command could be `["{python}", "run_python.py"]`. Suggested
distinct styles for future ports are green `#009E73` triangles (`^`), purple
`#CC79A7` diamonds (`D`) and dark gray `#444444` downward triangles (`v`).
Available markers: `o`, `s`, `^`, `D`, `v`, `p`.

The generator checks populated language directories and refuses to silently omit
an unregistered port. Registration does not create or imply a port implementation.

## Check cache behavior

```sh
python -m unittest test_verification_cache.py
```

These tests use temporary fixture libraries. They verify cache reuse, selective
invalidation, corruption recovery and the frozen-source update policy without
changing the real libraries or NASA data.

## Presentation and offline packaging

Comparison data tables are intentionally omitted. Future option: an opt-in table view or export using the retained calculation and comparison caches. Keep the report focused on charts and their difference captions by default.

After regenerating the report, run `node webapp/tools/prepare-release.mjs` from the repository root. This packages the report and its locally linked CSV, reference source, instructions and calculation records into the web app and fingerprints them for offline caching. All chart variants are embedded. The app’s US76 verification link stays within its installation scope. The NASA PDF stays in this research folder but is excluded from the app package and offline cache. The report links only to the original NASA source record, which provides access to the PDF. Do not add a separate PDF link. Wikipedia and NASA website links require internet access.

## Closing presentation

Omit the closing footer notes about offline files, caches, regeneration commands
and future table/export options from the report page. Keep those details in the
build documentation and relevant provenance disclosure instead.

## Shared educational-use notice (9 September 2026)

Follow the shared notice and final presentation step in [VERIFICATION.md](../../../../VERIFICATION.md#shared-report-notice-and-final-presentation-step). After the scientific generator, run `node webapp/tools/render-report-notices.mjs` from the repository root. The user explicitly requested all existing report presentations rebuilt for this notice; retain valid calculations, observations, plots and their execution timestamps. This presentation change does not establish a new numerical validation baseline.
