Skip to content

Commit a1bc802

Browse files
authored
Stabilize preflight, runners, and ERF artifacts (#55)
* sync ERF dependency pin and startup readiness docs * add first-run readiness red tests and integration clone coverage * Implement Phase 5 startup readiness preflight logic * Rebuild ERF FAISS artifacts and refresh schema rename outputs * Set default FAISS embedding model to lbl/nomic-embed-text * Add startup preflight hook in main with TTY/non-TTY coverage * Improve preflight mismatch remediation guidance and non-TTY hint * Improve interactive preflight UX for ERF mismatch and repo selection * Refactor executable discovery policy and runner fallbacks * Prefer case-derived solver over default in runners * Refactor solver compile flow to use config policy * Stream and log preflight clone progress with SSH fallback * Resolve local submit executable via solver build policy * Use solver policy for superfacility executable selection * Add interactive development+rebuild path for ERF commit mismatch * Propagate interactive repo selection and rerun preflight checks * Add tracked ERF first-run auto-setup matrix script * Add continue+rebuild option and progress logs for ERF mismatch * Make rebuild check optional and avoid repeated interactive rebuild loops * Waive same-run ERF mismatch after successful rebuild * Prefer runner run directory in visualization node * restore post-merge test contracts and clean ERF schema artifact * Remove scripts and local outputs * Added additional skips for spurious tests * Added preflight stubs to CLI integration tests * Implement code-gated viz mapping with clarification disambiguation * Gate solver-dependent viz tests and assert catalog hard-fail
1 parent 80ba696 commit a1bc802

105 files changed

Lines changed: 9684 additions & 8055 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dependencies.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"erf": {
1919
"url": "https://github.com/erf-model/ERF.git",
2020
"branch": "development",
21-
"commit": "1df48173da427f57a8201e157518afa7fd2e73ee"
21+
"commit": "5613ec3943a33d5f0b4f954e34c4e3ff5559a945"
2222
},
2323
"remora": {
2424
"url": "https://github.com/AMReX-Codes/REMORA.git",

database/configs/amrex_config.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,11 @@ class AMReXConfig(BaseAMReXConfig):
5252
priority_cases = [
5353
"Tests/Amr/Advection_AmrCore",
5454
]
55+
56+
@classmethod
57+
def get_plotfile_period_param(cls) -> str | None:
58+
return "amr.plot_per"
59+
60+
@classmethod
61+
def get_plotfile_step_interval_param(cls) -> str | None:
62+
return "amr.plot_int"

database/configs/base_amrex_config.py

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,32 @@ class BaseAMReXConfig:
172172

173173
default_exec_pattern: ClassVar[str | None] = None
174174
"""Glob pattern for default executable within default_exec_repo_path."""
175+
build_system_preference: ClassVar[str] = "gnumake"
176+
"""Preferred build system for executable discovery (e.g., gnumake, cmake)."""
177+
executable_search_path_templates: ClassVar[list[str]] = ["{central_build_dir}"]
178+
"""Ordered executable search templates used by runtime runner fallbacks."""
179+
cmake_executable_names: ClassVar[list[str]] = []
180+
"""Executable filenames emitted by CMake workflows (e.g., erf_exec)."""
181+
cmake_executable_ignores_accel_suffix: ClassVar[bool] = False
182+
"""If True, CMake executables are treated as feature-agnostic names."""
183+
gnumake_executable_globs: ClassVar[list[str]] = ["*.ex"]
184+
"""Executable glob patterns emitted by GNUmake workflows."""
185+
cmake_source_dir_template: ClassVar[str] = "{repo_root}"
186+
"""CMake source directory template for compile orchestration."""
187+
cmake_build_dir_template: ClassVar[str] = "{repo_root}/build"
188+
"""CMake build directory template for compile orchestration."""
189+
cmake_install_prefix_template: ClassVar[str | None] = None
190+
"""Optional CMake install prefix template."""
191+
cmake_configure_args: ClassVar[list[str]] = []
192+
"""Additional args for `cmake -S ... -B ...`."""
193+
cmake_build_args: ClassVar[list[str]] = []
194+
"""Additional args for `cmake --build ...`."""
195+
cmake_install_args: ClassVar[list[str]] = []
196+
"""Additional args for `cmake --install ...`."""
197+
gnumake_clean_targets: ClassVar[list[str]] = ["realclean"]
198+
"""GNUmake clean targets executed before build."""
199+
gnumake_build_args: ClassVar[list[str]] = ["USE_MPI=TRUE", "DEBUG=FALSE"]
200+
"""GNUmake build flag defaults."""
175201

176202
# === Solver Heuristics (Config-Driven) ===
177203
selection_keywords: ClassVar[list[str]] = []
@@ -2076,6 +2102,68 @@ def resolve_default_inputs_path(cls, repo_root: Path | None) -> Path | None:
20762102
return base / "inputs"
20772103
return None
20782104

2105+
@classmethod
2106+
def get_build_system_preference(cls) -> str:
2107+
return str(getattr(cls, "build_system_preference", "gnumake")).strip().lower()
2108+
2109+
@classmethod
2110+
def get_executable_search_path_templates(cls) -> list[str]:
2111+
templates = getattr(cls, "executable_search_path_templates", [])
2112+
return [str(item) for item in templates]
2113+
2114+
@classmethod
2115+
def get_cmake_executable_names(cls) -> list[str]:
2116+
names = getattr(cls, "cmake_executable_names", [])
2117+
return [str(item) for item in names]
2118+
2119+
@classmethod
2120+
def cmake_ignores_accel_suffix(cls) -> bool:
2121+
return bool(getattr(cls, "cmake_executable_ignores_accel_suffix", False))
2122+
2123+
@classmethod
2124+
def get_gnumake_executable_globs(cls) -> list[str]:
2125+
globs = getattr(cls, "gnumake_executable_globs", [])
2126+
return [str(item) for item in globs] if globs else ["*.ex"]
2127+
2128+
@classmethod
2129+
def get_cmake_source_dir_template(cls) -> str:
2130+
return str(getattr(cls, "cmake_source_dir_template", "{repo_root}"))
2131+
2132+
@classmethod
2133+
def get_cmake_build_dir_template(cls) -> str:
2134+
return str(getattr(cls, "cmake_build_dir_template", "{repo_root}/build"))
2135+
2136+
@classmethod
2137+
def get_cmake_install_prefix_template(cls) -> str | None:
2138+
value = getattr(cls, "cmake_install_prefix_template", None)
2139+
return None if value is None else str(value)
2140+
2141+
@classmethod
2142+
def get_cmake_configure_args(cls) -> list[str]:
2143+
return [str(item) for item in getattr(cls, "cmake_configure_args", [])]
2144+
2145+
@classmethod
2146+
def get_cmake_build_args(cls) -> list[str]:
2147+
return [str(item) for item in getattr(cls, "cmake_build_args", [])]
2148+
2149+
@classmethod
2150+
def get_cmake_install_args(cls) -> list[str]:
2151+
return [str(item) for item in getattr(cls, "cmake_install_args", [])]
2152+
2153+
@classmethod
2154+
def get_gnumake_clean_targets(cls) -> list[str]:
2155+
targets = getattr(cls, "gnumake_clean_targets", None)
2156+
if targets is None:
2157+
return ["realclean"]
2158+
return [str(item) for item in targets] or ["realclean"]
2159+
2160+
@classmethod
2161+
def get_gnumake_build_args(cls) -> list[str]:
2162+
args = getattr(cls, "gnumake_build_args", None)
2163+
if args is None:
2164+
args = getattr(cls, "gnumake_flags", ["USE_MPI=TRUE", "DEBUG=FALSE"])
2165+
return [str(item) for item in args]
2166+
20792167
@classmethod
20802168
def get_slurm_metadata(cls) -> dict[str, str]:
20812169
"""
@@ -2296,6 +2384,68 @@ def get_viz_variable_catalog(cls, repo_root: Path | None = None) -> list[dict[st
22962384
return []
22972385

22982386
@classmethod
2387+
def get_viz_tier1_intents(cls) -> dict[str, dict[str, Any]]:
2388+
"""
2389+
Return canonical semantic visualization intents (Tier 1).
2390+
"""
2391+
return {
2392+
"temperature": {"aliases": ["temperature", "temp", "thermal"]},
2393+
"velocity": {"aliases": ["velocity", "speed"]},
2394+
"vertical_velocity": {
2395+
"aliases": [
2396+
"vertical velocity",
2397+
"vertical_velocity",
2398+
"w-velocity",
2399+
"w velocity",
2400+
"updraft",
2401+
"downdraft",
2402+
]
2403+
},
2404+
"pressure": {"aliases": ["pressure", "pres"]},
2405+
"density": {"aliases": ["density", "rho"]},
2406+
"vorticity": {"aliases": ["vorticity", "vort"]},
2407+
"cloud_water": {
2408+
"aliases": [
2409+
"cloud water",
2410+
"cloud_water",
2411+
"liquid water",
2412+
"cloud liquid",
2413+
"qc",
2414+
]
2415+
},
2416+
}
2417+
2418+
@classmethod
2419+
def build_viz_tier2_candidates(cls, repo_root: Path | None = None) -> dict[str, list[dict[str, Any]]]:
2420+
"""
2421+
Build solver candidates (Tier 2) from live source catalog.
2422+
"""
2423+
catalog = cls.get_viz_variable_catalog(repo_root=repo_root)
2424+
if not catalog:
2425+
return {}
2426+
2427+
intents = cls.get_viz_tier1_intents()
2428+
candidates: dict[str, list[dict[str, Any]]] = {}
2429+
for token, spec in intents.items():
2430+
aliases = {token.lower()}
2431+
for alias in spec.get("aliases", []) or []:
2432+
aliases.add(str(alias).strip().lower())
2433+
token_candidates: list[dict[str, Any]] = []
2434+
for entry in catalog:
2435+
if not isinstance(entry, dict):
2436+
continue
2437+
name = str(entry.get("name", "")).strip()
2438+
if not name:
2439+
continue
2440+
entry_aliases = {name.lower()}
2441+
for alias in entry.get("aliases", []) or []:
2442+
entry_aliases.add(str(alias).strip().lower())
2443+
if aliases.intersection(entry_aliases):
2444+
token_candidates.append(dict(entry))
2445+
if token_candidates:
2446+
candidates[token] = token_candidates
2447+
return candidates
2448+
22992449
def get_default_slice_axis(cls) -> str | None:
23002450
"""
23012451
Return preferred default slice-normal axis for visualization.
@@ -2304,6 +2454,50 @@ def get_default_slice_axis(cls) -> str | None:
23042454
"""
23052455
return None
23062456

2457+
@classmethod
2458+
def get_plotfile_var_param(cls) -> str:
2459+
"""
2460+
Return solver-specific parameter key for plot variable selection.
2461+
"""
2462+
return "amr.plot_vars"
2463+
2464+
@classmethod
2465+
def get_plot_var_param_candidates(cls) -> list[str]:
2466+
"""
2467+
Return ordered plot-var ParmParse candidate keys (primary first).
2468+
"""
2469+
return [cls.get_plotfile_var_param()]
2470+
2471+
@classmethod
2472+
def get_plotfile_period_param(cls) -> str | None:
2473+
"""
2474+
Return solver-specific time-based plot cadence parameter, if supported.
2475+
"""
2476+
return None
2477+
2478+
@classmethod
2479+
def get_plotfile_step_interval_param(cls) -> str | None:
2480+
"""
2481+
Return solver-specific step-based plot interval parameter, if supported.
2482+
"""
2483+
return None
2484+
2485+
@classmethod
2486+
def supports_physical_time_cadence(cls) -> bool:
2487+
"""
2488+
Return whether solver time-based cadence can be interpreted from seconds.
2489+
"""
2490+
return True
2491+
2492+
@classmethod
2493+
def convert_plot_cadence_prompt_seconds_to_solver_time(cls, seconds: float) -> float | None:
2494+
"""
2495+
Convert prompt seconds into solver-time cadence units.
2496+
2497+
Default behavior assumes solver time is seconds (identity transform).
2498+
"""
2499+
return float(seconds)
2500+
23072501
@classmethod
23082502
def _resource_bytes_per_cell(cls, config: dict[str, Any]) -> int:
23092503
return 200

database/configs/erf_config.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ def get_default_slice_axis(cls) -> str | None:
2929
"""
3030
return "y"
3131

32+
@classmethod
33+
def get_plotfile_var_param(cls) -> str:
34+
return "erf.plot_vars_1"
35+
36+
@classmethod
37+
def get_plotfile_period_param(cls) -> str | None:
38+
return "erf.plot_per_1"
39+
40+
@classmethod
41+
def get_plotfile_step_interval_param(cls) -> str | None:
42+
return "erf.plot_int_1"
43+
44+
@classmethod
45+
def get_plot_var_param_candidates(cls) -> list[str]:
46+
return ["erf.plot_vars_1", "amr.plot_vars", "plot_vars"]
47+
3248
# === Registry Metadata ===
3349
github_org = "erf-model"
3450
github_repo = "ERF"
@@ -38,6 +54,29 @@ def get_default_slice_axis(cls) -> str | None:
3854
default_inputs_path = "Exec/RegTests/Bubble/inputs"
3955
default_exec_repo_path = "Exec/RegTests/Bubble"
4056
default_exec_pattern = "ERF*ex"
57+
build_system_preference = "cmake"
58+
preferred_build_system = "cmake"
59+
executable_search_path_templates = [
60+
"{repo_root}/build/Exec",
61+
"{repo_root}/Build/Exec",
62+
"{repo_root}/install/bin",
63+
"{central_build_dir}",
64+
]
65+
cmake_executable_names = ["erf_exec"]
66+
cmake_executable_ignores_accel_suffix = True
67+
gnumake_executable_globs = ["ERF*ex"]
68+
cmake_source_dir_template = "{repo_root}"
69+
cmake_build_dir_template = "{repo_root}/build"
70+
cmake_install_prefix_template = None
71+
cmake_configure_args = [
72+
"-DCMAKE_BUILD_TYPE=Release",
73+
"-DERF_ENABLE_MPI=ON",
74+
]
75+
cmake_build_args = []
76+
cmake_install_args = []
77+
gnumake_clean_targets = ["realclean"]
78+
gnumake_build_args = ["USE_MPI=TRUE", "DEBUG=FALSE"]
79+
gnumake_flags = ["USE_MPI=TRUE", "DEBUG=FALSE"]
4180

4281
selection_keywords = [
4382
"abl",

database/configs/pelelmex_config.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,22 @@ class PeleLMeXConfig(BaseAMReXConfig):
167167
"prompt": "What {section}.atol and {section}.rtol should I use for PeleLMeX with a QSSA mechanism?",
168168
}
169169

170+
@classmethod
171+
def get_plotfile_var_param(cls) -> str:
172+
return "peleLM.derive_plot_vars"
173+
174+
@classmethod
175+
def get_plot_var_param_candidates(cls) -> list[str]:
176+
return ["peleLM.derive_plot_vars", "amr.plot_vars", "plot_vars"]
177+
178+
@classmethod
179+
def get_plotfile_period_param(cls) -> str | None:
180+
return "amr.plot_per"
181+
182+
@classmethod
183+
def get_plotfile_step_interval_param(cls) -> str | None:
184+
return "amr.plot_int"
185+
170186
prompt_templates: ClassVar[dict[str, Any]] = {
171187
"misc": {
172188
"schema_scan": """Identify requested concepts from the case description that do not map to known baseline or schema parameters.

database/configs/remora_config.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ def get_default_slice_axis(cls) -> str | None:
2929
"""
3030
return "y"
3131

32+
@classmethod
33+
def get_plotfile_period_param(cls) -> str | None:
34+
return "remora.plot_int_time"
35+
36+
@classmethod
37+
def get_plotfile_step_interval_param(cls) -> str | None:
38+
return "remora.plot_int"
39+
3240
# === Registry Metadata ===
3341
github_org = "AMReX-Codes"
3442
github_repo = "REMORA"

database/faiss/cborg/build_session_manifest.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
{
2+
"build_script": "build_all_indices.py",
23
"entries": [
4+
{
5+
"build_script": "build_all_indices.py",
6+
"dependencies_commit": null,
7+
"embedding_dimension": null,
8+
"embedding_model": "lbl/nomic-embed-text",
9+
"embedding_provider": "cborg",
10+
"generated_at": "2026-03-18T14:44:08.389712+00:00",
11+
"level": "0",
12+
"manifest_path": "level0/faiss_provenance.json",
13+
"repo_commit": null,
14+
"solver": null,
15+
"version": "1"
16+
},
17+
{
18+
"build_script": "build_all_indices.py",
19+
"dependencies_commit": "5613ec3943a33d5f0b4f954e34c4e3ff5559a945",
20+
"embedding_dimension": null,
21+
"embedding_model": "lbl/nomic-embed-text",
22+
"embedding_provider": "cborg",
23+
"generated_at": "2026-03-18T14:45:12.017072+00:00",
24+
"level": "1",
25+
"manifest_path": "level1/erf_faiss_provenance.json",
26+
"repo_commit": "5613ec3943a33d5f0b4f954e34c4e3ff5559a945",
27+
"solver": "erf",
28+
"version": "1"
29+
},
330
{
431
"build_script": "build_all_indices.py",
532
"dependencies_commit": "99914444329f6be784c6a153581c53bc60ae8937",
@@ -26,6 +53,19 @@
2653
"solver": "erf",
2754
"version": "1"
2855
},
56+
{
57+
"build_script": "build_all_indices.py",
58+
"dependencies_commit": "5613ec3943a33d5f0b4f954e34c4e3ff5559a945",
59+
"embedding_dimension": null,
60+
"embedding_model": "lbl/nomic-embed-text",
61+
"embedding_provider": "cborg",
62+
"generated_at": "2026-03-18T14:58:05.501994+00:00",
63+
"level": "2",
64+
"manifest_path": "level2/erf_faiss_provenance.json",
65+
"repo_commit": "5613ec3943a33d5f0b4f954e34c4e3ff5559a945",
66+
"solver": "erf",
67+
"version": "1"
68+
},
2969
{
3070
"build_script": "build_all_indices.py",
3171
"dependencies_commit": "a6b4dff152c2cad2cf0edee58099eefffd2ba328",
@@ -66,5 +106,6 @@
66106
"version": "1"
67107
}
68108
],
109+
"generated_at": "2026-03-18T14:58:05.507710+00:00",
69110
"version": "1"
70111
}
-132 KB
Binary file not shown.
-113 KB
Binary file not shown.
-42 KB
Binary file not shown.

0 commit comments

Comments
 (0)