systems/CAPABILITY_LEDGER.md
Authority. This is an ORIENTATION doc (DOC_MAP authority rank 6). It records **measured facts
about a machine**, never world canon. Where it touches canon it CITES canon and never restates it.
Canon's pipeline requirements live at _source/02_Tier_2_Region_Pages/*.md §1 and §17 and the
docs/pipeline_review/tech_research/ dossiers; those win every conflict with this file.
Method (so any lane can re-derive, not re-trust). Every "STANDING" row below was verified by
running something on MILKS5090 on 2026-08-02 — a binary invoked, a port probed, a config file
read, a version string printed. No row is carried from a doc. Where a claim could not be reduced to
a command, it is labelled [UNPROVEN] and says what would prove it. The re-verify commands are in
§6.
---
Ranked by work unblocked per minute of Josh's time. Items 1-3 are tonight; everything below
the line is not blocking anything this week.
| # | What | Time | Cost | Unblocks |
|---|---|---|---|---|
| 1 | OpenTopography API key | ~3 min | free | The ENTIRE terrain chain. 69 regions. Also the Flores rasters canon already cites, which are NOT on this box |
| 2 | Gaea Professional — buy + activate | ~10 min | $199 | Erosion automation for 69 regions. VERIFIED gated: the CLI runs and writes nothing today |
| 3 | HuggingFace account + read token | ~5 min | free | The ~350-450 GB Tier-1 model pull — 3D, video, voice, music, the whole generative floor |
| — | *(line: everything above is tonight, everything below can wait)* | |||
| 4 | Confirm which Epic account is signed in on this box | ~1 min | free | MetaHuman cloud autorig + Fab. Probably already done — verify, don't redo |
| 5 | OpenTopography Plus (only if 50 calls/24 h proves too slow) | ~5 min | unpublished | Compresses a ~3-day DEM fetch into one night. Do NOT buy yet — §4.1 says why |
| 6 | Meta Llama-3-8B-Instruct gated-repo acceptance | ~2 min | free | ARDY only, which is a Tier-3 EVAL lane. Defer. Do not accept a Meta licence for a lane we may not adopt |
Do this: go to portal.opentopography.org → create an account (email + password) → **My
Account** → request an API key → copy the key → send it to the lane, or set it yourself with:
setx OPENTOPOGRAPHY_API_KEY "<the-key>"
Why it is #1. Tools/terrain_fetch_preprocess.py:358 exits with
no OPENTOPOGRAPHY_API_KEY in env or registry and there is no key in this box's environment or in
HKCU:\Environment (checked both — the tool checks both, at :105 and :111). So **zero terrain
can be fetched on this machine right now.**
And it is worse than "future regions are blocked": _source/02_Tier_2_Region_Pages/flores_island.md:63
cites measurements taken from Saved/Terrain/flores_island_heightmap_5611x1531.r16 and
flores_island_wc_crop.png. Saved/Terrain is a junction to E:\terrain, and **E:\terrain is
empty.** Those rasters were made on the old machine. The canon rows stand — they were honestly
derived — but the artifacts behind them cannot be re-derived on this box until the key exists.
What it costs: nothing. Free tier, non-academic = 50 API calls per 24 hours. The tool
already enforces exactly that ceiling itself (terrain_fetch_preprocess.py:139) and content-caches
every DEM so re-runs never re-hit the API.
Do this: quadspinner.com/compare → Professional, $199 → purchase → launch
C:\Program Files\QuadSpinner\Gaea 2\Gaea.exe → sign in / enter the licence → accept the EULA
(C:\Program Files\QuadSpinner\Gaea 2\EULA.txt).
This was verified on-box, not assumed, and it is the answer to the question canon left open.
docs/pipeline_review/tech_research/GEODATA_TERRAIN_CHAIN.md:533-535 explicitly records the
tier-gating of Gaea's CLI as UNCONFIRMED and says "get a direct answer from QuadSpinner before
assuming Indie suffices." That question is now closed, by two independent lines of evidence:
1. The vendor's own comparison table (quadspinner.com/compare, fetched 2026-08-02) carries a
row labelled "Automation" with checkmarks on Professional and Enterprise only — Community
and Indie are ✗. The adjacent "Expose Parameters" and "Variables and Expressions" rows split the
same way, which is the whole --vars / -v surface the CLI advertises.
2. The box agrees. Gaea 2.3.0.1 is installed and Gaea.Swarm.exe (the CLI) is present and
prints its full help at exit 0. Driven at a real graph it does this:
Preparing Gaea Build Swarm 2.3.0.1...
Loading devices...
Activated AMD Ryzen 9 9950X3D2 16-Core Processor...
Opening Canyon River with Sea.terrain...
…and then exits 0 having written zero files. Two different example graphs, one of them
carrying 58 save/export markers. The edition record
%APPDATA%\QuadSpinner\Gaea\2.0\edition.dat is 2 bytes — a bare CRLF. No edition activated.
One alternative hypothesis was tested and eliminated: the free tier's cap is 1024×1024, so a
resolution gate would have let a --resolution 512 build through. It did not. The no-op is not
about resolution.
A second reason Professional is required that no doc in the repo has recorded yet.
GEODATA_TERRAIN_CHAIN.md:345-348 argues Indie is *nearly* enough because its 8,192 cap "lines up
almost exactly with UE Landscape's." That reasoning misses the row beside it: **tiled builds are
Not-Supported on Community and Indie**, and Professional unlocks them to 262,144². Region-page §17
requires "UE Landscape import tiles under World Partition at the 8,129-vertex actor cap"
(flores_island.md:107). A tiled Landscape import wants tiled builds. So even a hypothetical
hand-driven Indie workflow would be building the wrong shape.
Enterprise is $299 (+$100). It is NOT recommended — nothing in the researched chain needs what
it adds over Professional. Buy Professional.
Do this: huggingface.co → sign up → Settings → Access Tokens → New token → type: Read →
copy → send it to the lane or set it:
setx HF_TOKEN "<the-token>"
Why: the ruled Tier-1 install manifest
(docs/pipeline_review/tech_research/PIPELINE_STACK_SYNTHESIS_2026-07-29.md §2.1) is ~170-200 GB
of HuggingFace-hosted weights and the full roster is ~350-450 GB. HF_HOME and
HUGGINGFACE_HUB_CACHE are already set to D:\hf on this box, but no token exists anywhere —
no HF_TOKEN in either environment scope, no ~/.cache/huggingface/token. Anonymous pulls work
for public repos and are rate-limited; a read token makes an overnight 400 GB pull reliable rather
than lucky. A read token grants read only — it cannot spend money, publish, or modify anything.
CLOSED. Read directly off the running Launcher: the account in the bottom-left corner is
Milkman3790, signed in. It is the correct one by construction rather than by choice -- the
Launch button reads Unreal Engine 5.8.1, so this account owns the engine install, which is
what makes MetaHuman cloud auto-rig and any Fab acquisition resolve into THIS project rather than
a different library. Fab sits in the Launcher left nav under Unreal Engine.
Josh asked whether it was josh.milks or joshua.milks90. It is neither. Recorded so the
question is never re-asked and so no lane tries to infer it from the two GUID folders under
%LOCALAPPDATA%\EpicGamesLauncher\Saved\UserVaultSettings\, which carry no readable name.
Nothing was needed from Josh -- it was already authenticated. This item said "probably already
done, verify don't redo", and that was right.
Two account records exist under
%LOCALAPPDATA%\EpicGamesLauncher\Saved\UserVaultSettings\ and UE 5.8.1 was installed through the
Launcher, which is not possible signed-out. So this is a confirm, not a task. Josh: open the
Epic Games Launcher and read the account name in the corner, and tell the lane which one it is.
It matters because §17 of every region page requires it:
"MetaHuman batch generation round-trips Epic's cloud for the named cast"
(flores_island.md:1728). That is confirmed on-box, not inferred — MetaHumanSDK's shipped
config names live Epic endpoints including mh-uemhc-autorig-service…on.epicgames.com/v1/autorigs
and mh-texture-synthesis-service…on.epicgames.com. Fab ships in-engine at
Engine/Plugins/Fab/Fab.uplugin. Both want the signed-in account.
---
*This section exists because of the failure this run was convened to fix: a session asked Josh to
re-decide the contents of the Flores concept-art board when docs/spine/CH_02.md:226 had already
listed them, typed and id'd. The following are settled in canon. A lane that re-opens one of them
is the defect.*
| Looks like a question | Already settled | Where |
|---|---|---|
| "Which DEM source should we use?" | COP30 (Copernicus GLO-30) via the OpenTopography API | flores_island.md:103 |
| "What meters-per-vertex?" | A per-region compression decision with a stated first pass: 2.0 m/vertex for highland corridors, tighter at hero-sites. The 30.0 m in the recorded smoke is labelled in canon itself as the tool's native-COP30 SMOKE value | flores_island.md:103-105, :112-113 |
| "How do we get landcover?" | ESA WorldCover → material-layer weightmaps | flores_island.md:107-108 |
| "Where does erosion happen?" | A Gaea pass between GDAL and UE — not download, not import | flores_island.md:106; GEODATA_TERRAIN_CHAIN.md:366-372 |
| "How does registry data reach the engine?" | DataTables, one C++ USTRUCT per registry; PCG consumes Zone Catalog + DataTables | flores_island.md:1722-1725 |
| "Which agent surface runs which step?" | The three-seam routing: NeoStack = judgment, UE Python/Remote-Control = bulk/CI, Epic MCP = PCG | flores_island.md:1727-1728 |
| "What image format for plates?" | 16-bit PNG for plates and albedo, EXR for lighting studies, PNG/TGA for texture | docs/proposals/CONCEPT_ART_PROGRAM.md:727 |
| "How many plates are we making?" | ~12,800 FLOOR → ~17,880 TARGET full game; ~2,525 → ~3,470 for the slice | CONCEPT_ART_PROGRAM.md:74-75 |
---
Machine. MILKS5090 — Ryzen 9 9950X3D (16C/32T), 128 GB, **RTX 5090 32 GB, driver 596.36,
CUDA 13.2**, idle 43 °C / 19 W. Verified nvidia-smi.
| Lane | Status | The measurement |
|---|---|---|
| GPU / CUDA | ✅ STANDING | sm_120 confirmed live: torch.cuda.get_device_capability() → (12, 0) in both ComfyUI environments |
| Image generation | ✅ STANDING, PRODUCING | ComfyUI with Z-Image-Turbo (z_image_turbo_bf16.safetensors, 12 GB) + qwen_3_4b text encoder (7.5 GB) + ae VAE. 23 real PNGs on disk, generated today, including a 20-step 2048² at 1.64 s/it → 34.07 s/image |
| Art venv | ✅ STANDING, ON THE RULED PIN | D:\comfyui\.venv-art runs torch 2.9.0+cu128 — exactly the synthesis §2.3 pin. (The portable tree still runs 2.13.0+cu130; both report sm_120, but the ruled lane is the .venv-art one) |
| Music / audio gen | ✅ SMOKE PASSED | ace_step_1.5_turbo_aio.safetensors (9.4 GB) present; output/audio/kt4_acestep_smoke.mp3 (804 KB) produced today |
| Local LLM | ✅ STANDING | Ollama on 127.0.0.1:11434, 6 models: qwen3 0.6b/1.7b/4b/8b/14b + phi4:14b. Per-tier t/s and VRAM measured (C:\dev\setup_artifacts\baselines.md) |
| Embeddings / RAG | ✅ STANDING | fastembed 0.8.0 + sqlite-vec 0.1.9; bge-small-en-v1.5 + multilingual-MiniLM in D:\fastembed; 10,616 chunks in 110.7 s |
| UE + NeoStack | ✅ STANDING | UE 5.8.1, Changelist 56057345, 31 GB at C:\Program Files\Epic Games\UE_5.8. NeoStackAI + ModelContextProtocol + PCG + PCGToolset + StateTree all enabled in the uproject |
| MetaHuman + Fab | ✅ PRESENT (needs account) | 10 MetaHuman plugins ship in-engine incl. MetaHumanCharacter ("MetaHuman Creator") and MetaHumanGenerator; Fab.uplugin present. Not enabled in the uproject yet — that is a lane task, not a Josh task |
| Gaea | ⚠️ INSTALLED, UNLICENSED | 2.3.0.1 + Gaea.Swarm.exe CLI. Drive layout already configured (Builds→E:\terrain\gaea\builds, Cache→D:\gaea_cache, EXR heightfield / PNG16 masks). edition.dat = 2 bytes. Builds write nothing. → Josh #2 |
| OCR | ✅ WEIGHTS PRESENT | DeepSeek-OCR + PaddleOCR-VL in D:\hf\hub; Tesseract-OCR installed |
| WSL2 | ✅ PRESENT, IDLE | Ubuntu-24.04, WSL v2, currently Stopped. No Docker — the 3D lane's containment route needs it |
| Gates | ✅ GREEN | harness/run_gates.py → exit 0 on this tree today, incl. the new orientation and canon_derivation gates |
What is NOT here at all (verified absent, no wishful reading):
| Missing | Lane it blocks | Class |
|---|---|---|
rasterio (Python) | The whole terrain chain — the tool cannot import | (a) |
| Blender | 3D CPU finishing: retopo, UV, LOD, collision, FBX/glTF export | (a) |
| ffmpeg | Video/audio post on every media lane | (a) |
| Docker / NVIDIA Container Toolkit | The 3D lane's WSL2 containment route | (a) |
| HiDream-O1 + Gemma-4 encoder; Depth-Anything-3; SeedVR2 | Hero plates ≥2048², depth control, upscale | (b→3) |
| TRELLIS.2-4B, Direct3D-S2, Hunyuan3D-2.1 | All image→3D. Nothing on this box makes a mesh | (b→3) |
| Wan 2.2 | All video | (b→3) |
| Kokoro, Piper, Qwen3-TTS, Chatterbox | All voice | (b→3) |
| ACE-Step XL-SFT, MOSS-SoundEffect | Full-quality music; bulk SFX | (b→3) |
| Kimodo / ARDY | All text→motion | (b→3) |
| DEM + WorldCover rasters | Terrain, and the artifacts flores_island.md:63 cites | (c→OpenTopo key) |
---
Canon (flores_island.md:103-108): COP30 via OpenTopography → GDAL/rasterio recipe → Gaea erosion
pass → UE Landscape import tiles under World Partition at the 8,129-vertex actor cap → ESA
WorldCover to material-layer weightmaps.
| Step | Canon says | Standing | Verdict |
|---|---|---|---|
| DEM fetch | COP30 via OpenTopography API | Tool written and hardened; no key | ⛔ Josh #1 |
| Reproject / void-fill / 16-bit out | rasterio recipe, absolute-metre datum | rasterio not installed | 🔧 (a) — one command |
| Erosion | Gaea pass, scripted across regions | CLI present, writes nothing | ⛔ Josh #2 |
| Landcover | ESA WorldCover COGs | --worldcover path exists; needs the same fetch env | 🔧 rides (a) |
| UE Landscape import | Python path, C++ shim as fallback | Tools/import_flores_landscape.py present; UE 5.8.1 standing | ✅ ready once fed |
The one honest surprise: the terrain tool needs rasterio only — it imports
rasterio, rasterio.fill, rasterio.transform, rasterio.warp, numpy, requests
(terrain_fetch_preprocess.py:48-53). It never imports osgeo. No separate GDAL install is
required; rasterio's wheel bundles GDAL. Any plan budgeting a GDAL/conda install for this chain is
budgeting work that does not exist.
| Canon requirement | Cite | Standing |
|---|---|---|
| Registry data → DataTables, one C++ USTRUCT per registry | :1666-1667 | ✅ Tools/import_registry_datatable.py, gen_row_struct.py, registry_import_manifest.json all present |
| PCG consumes Zone Catalog + DataTables | :1667-1669 | ✅ PCG + PCGToolset enabled |
| Landscape import via Python path | :1669-1670 | ✅ tooling present; ⛔ starved of input (§2.1) |
| Scene rows drive Sequencer | :1670-1671 | ✅ T0_Scene_Spec_Registry — 16 rows, carries generation_status |
| Three-seam routing | :1671-1672 | ✅ NeoStackAI + ModelContextProtocol enabled |
| MetaHuman batch round-trips Epic's cloud | :1672-1673 | ✅ plugins + live cloud endpoints present; needs account (Josh #4) and uproject enablement (lane task) |
| String tables / FText for every player-facing string | :1675-1683 | ✅ canon-side; no machine dependency |
879 registry rows across 12 registries carry generation_status (counted live today):
Boss 281 · Character 164 · Creature 150 · Weapon 72 · Antagonist 64 · Vril_Site 42 · SFX 30 ·
Voice 23 · Familiar 22 · Scene_Spec 16 · Theme 14 · Equipment 1.
Against that demand the box today has image and music only. There is no path from any of those
879 rows to a mesh, a voice line, a video, or an animation — those four lanes have
zero weights installed. That is the honest shape of the gap: the dispatcher is armed (GATE 36) and
the queue is full, and four of six output modalities have nothing to dispatch to.
---
| # | What | Command | Note |
|---|---|---|---|
| a1 | rasterio | python -m pip install rasterio | Verified available: rasterio-1.5.0-cp314-cp314-win_amd64.whl, 30.9 MB, pulled at 50 MB/s in a dry probe today. Python here is 3.14.6 and the cp314 wheel exists. Unblocks the entire fetch/preprocess half of the terrain chain the moment Josh's key lands |
| a2 | ffmpeg | winget install Gyan.FFmpeg | Media post on every lane |
| a3 | Blender 5.2 LTS | winget install BlenderFoundation.Blender | GPL tool; output is unencumbered. The 3D CPU finishing rail (synthesis §3.1 Class A) is the lane's real throughput win and needs zero VRAM |
| a4 | Docker Desktop + NVIDIA Container Toolkit | winget install Docker.DockerDesktop | Only if the 3D lane takes the WSL2 route. WSL2/Ubuntu-24.04 is already installed and idle |
| a5 | Public-repo weight pulls (Wan 2.2, TRELLIS.2, Z-Image siblings…) | hf download … | Works anonymously; a token (Josh #3) makes a 400 GB overnight reliable |
| a6 | Enable MetaHuman + Fab plugins in the uproject | uproject edit | Engine-side; needs Josh #4 only at first *cloud call*, not to enable |
**These are downloads of third-party software onto Josh's machine. They are named here with exact
commands and are NOT executed by this lane without the director's go.**
| Blocked | Waiting on | Why |
|---|---|---|
| Gaea erosion across 69 regions | (b) Gaea Pro AND (a1) rasterio AND (b) OpenTopo key | Three-deep chain; the erosion pass has no input until fetch+preprocess runs |
| UE Landscape import | the whole of §2.1 | Nothing to import |
Re-deriving flores_island.md:63's cited rasters | (b) OpenTopo key | E:\terrain is empty |
| Image→3D (879 rows' mesh demand) | the cu128 extension rebuild | Synthesis §2.2 headline: every 3D repo pins cu124/cu121 and none load on sm_120. Called "the single biggest unbudgeted cost." Half-day to two days of engineering — not a purchase, not an account |
| ARDY motion lane | Josh #6 (Meta gated repo) | Tier-3 eval only. Deliberately deferred |
| Sonniss SFX archive | nothing technical | Licence prohibits AI/ML training (synthesis §2.1). Usable as-is, never as training data |
The blocker that outranks every purchase on this page. harness/run_gates.py → the
build_readiness gate reports today:
- AssetGen: BLOCKED-ON(per-asset morphology/asset_concept field (§4.1 prompt input);
asset_category / mesh_tags field (mesh-taggable material routing))
- Combat: BLOCKED-ON(EG_ environment-grammar ids for the combat surfaces)
- Cinematic: BLOCKED-ON(scene-index beat_ref binding; scene_type field; participant_refs field)
- Audio: BLOCKED-ON(Section-10 machine cue table — the composition briefs are prose)
Read that carefully: none of those four are hardware, money, or an account. Buy Gaea, land the
OpenTopography key, pull all 450 GB of weights, and the AssetGen dispatcher still cannot emit a
prompt, because the field it would read from — the per-asset asset_concept / morphology input —
does not exist on the rows. This is authoring work inside the registries, it is entirely ours, it
needs zero GPU and zero spend, and it is the true head-of-chain for the 879-row generative queue.
It should be running in parallel with Josh's four items, not after them.
---
| Drive | Device | Size | Free | Role |
|---|---|---|---|---|
| C: | Kingston Fury Renegade Gen5 4 TB | 3.71 TB | 3.49 TB (94%) | Windows · UE engine (31 GB) · DDC · repos |
| D: | Samsung 990 Pro Gen4 4 TB | 3.64 TB | 3.54 TB (97%) | Models · ComfyUI · venvs · caches |
| E: | Samsung 870 QVO 8 TB SATA | 7.28 TB | 7.28 TB (100%) | Archive · terrain · audio libs · QA archives |
| 14.63 TB | 14.31 TB free |
Junctions already correct: Humanity/Saved/Terrain → E:\terrain,
humanity-forgotten/.rag → D:\rag_store. Current occupancy: UE engine 31 GB · game project 7.7 GB
(4.8 GB Intermediate) · DDC 0.8 GB · ComfyUI weights 29.2 GB · canon repo 119 MB.
Measured on today's real Z-Image output (8-bit PNG):
| Resolution | Mean file |
|---|---|
| 1024² | 1.53 MB |
| 1344² | 2.75 MB |
| 2048² | 6.64 MB |
Canon rules 16-bit PNG for plates (CONCEPT_ART_PROGRAM.md:727), so a shipped 2048² plate is
roughly double the measured 8-bit figure — call it ~13 MB.
| Bucket | Basis | Projection |
|---|---|---|
| Final plates, full game | 17,880 TARGET × ~13 MB @2048² 16-bit | ~230 GB |
| Candidate sweeps @ 10:1, kept at 1024² preview | 178,800 × 1.53 MB | ~270 GB |
| Worst case: every candidate kept at full res 16-bit | 178,800 × 13 MB | ~2.3 TB |
| Model roster (Tier 1 + 2, deduped) | synthesis §2.1 | 350-450 GB |
| Terrain: Gaea EXR heightfields + PNG16 masks, 69 regions | 4096² tier | ~35-70 GB |
| Same, at Professional's 16k tiled builds | 16× | 0.5-1.1 TB |
| UE DDC + cooked content, 69-region World Partition | [UNPROVEN — measure at first cook] | 0.2-1 TB |
| Sonniss archive (optional) | 7.47 GB + ~200 GB historical | ≤207 GB |
Verdict: storage is NOT a gate and Josh should buy nothing. The realistic band is
~1.5-2.5 TB over the life of the project; the pessimistic band with every full-res candidate
retained is ~4.5 TB. Against 14.31 TB free, the pessimistic case still leaves ~9 TB.
The one layout rule worth stating: candidate sweeps belong on E: (8 TB SATA, 100% free,
archive-class — sequential writes of finished PNGs do not want the Gen5). Keep D: for weights
and hot caches, and C: for the engine, DDC and repos. That is already how the box is
partitioned and how Gaea's Locations block is already pointed; nothing needs moving.
---
1. GEODATA_TERRAIN_CHAIN.md:533-535 can be closed. It carries "whether Gaea's CLI/automation
features are gated to Professional/Enterprise … is unconfirmed" as an open item. §0 item 2 above
closes it with the vendor table plus an on-box reproduction. A lane should retire that open item
and record the resolution; this ledger is not authorised to edit a pipeline_review doc.
2. Gaea's GPU is configured but not active in CLI runs. [UNPROVEN cause.]
Preferences.options lists AdaptiveCpp/GpuDiscrete/CUDA/NVIDIA/NVIDIA GeForce RTX 5090 first
in Compute.Backends, and the device scan finds and passes the 5090 (Logs\Devices.txt:
"Compute test passed"). But every Swarm run logs Active Devices: AMD Ryzen 9 9950X3D (Native)
only. This may be a consequence of the unlicensed state or a Swarm-specific device selection —
it cannot be disambiguated until item 2 is licensed. Re-check it in the first post-licence
run: if erosion for 69 regions runs CPU-only, the nightly terrain budget is wrong by a large
factor. This is the single most important thing to re-measure the moment Gaea activates.
---
nvidia-smi # GPU, driver, VRAM
ollama list # local LLM roster
netstat -ano | findstr LISTENING # 11434 = Ollama; 8188/8189 = ComfyUI
D:\comfyui\.venv-art\Scripts\python.exe -c "import torch;print(torch.__version__,torch.cuda.get_device_capability())"
python -c "import rasterio" # terrain chain gate
type "%APPDATA%\QuadSpinner\Gaea\2.0\edition.dat" # 2 bytes = unlicensed
"C:\Program Files\QuadSpinner\Gaea 2\Gaea.Swarm.exe" --filename "<any .terrain>" --buildpath <dir> --resolution 512 --silent
# licensed => files appear; unlicensed => exit 0, nothing written
reg query HKCU\Environment /v OPENTOPOGRAPHY_API_KEY # terrain key
dir E:\terrain # empty = canon's cited rasters absent
python harness\run_gates.py # must exit 0