Skip to content

Add SimBoard-compatible www inference via a new [simboard] config section#841

Draft
forsyth2 with Copilot wants to merge 12 commits into
mainfrom
copilot/update-default-www-and-simboard-type
Draft

Add SimBoard-compatible www inference via a new [simboard] config section#841
forsyth2 with Copilot wants to merge 12 commits into
mainfrom
copilot/update-default-www-and-simboard-type

Conversation

Copilot AI commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in [simboard] configuration section that lets zppy infer the [default] www path automatically instead of requiring users to set it explicitly. This targets SimBoard-compatible publishing, where the diagnostics archive path can be derived from Mache's web_portal.base_path.

Expected behavior:

simboard.enabled www Behavior
False any zppy does nothing SimBoard-specific.
True empty Infer the SimBoard archive path from mache.
True set Use www as the output path and do not override it. simboard.enabled still controls SimBoard-specific metadata and validation.
True empty, but path cannot be inferred Raise a clear configuration error.

Changes

New [simboard] config section (zppy/defaults/default.ini)

  • enabled (bool, default False): opts in to SimBoard-compatible publishing.
  • simulation_type (option: production | development | none, default production): selects the archive classification used when inferring www.
  • [default] www no longer requires an explicit value (string(default="") instead of a bare string), since it can now be inferred.

New module zppy/simboard.py

  • simboard(...): a configuration-only task hook (no HPC job), analogous to [bundle], that validates the [simboard] section has no subsections.
  • simboard_enabled(config): parses enabled from bool or "true"/"false" strings (case-insensitive), raising ValueError on anything else.
  • validate_simboard_config(config): rejects simulation_type = "none" whenever enabled = True.
  • normalize_web_portal_base_path(...): strips whitespace and trailing slashes.
  • infer_simboard_www(machine_info, config): builds <web_portal base_path>/diagnostics_archive/<simulation_type>/, raising a descriptive ValueError if Mache has no (or an empty) web_portal.base_path for the current machine.

zppy/__main__.py

  • _determine_parameters now calls a new _set_default_www helper, which:
    • Always runs validate_simboard_config (so simulation_type is checked even when www is already explicitly set).
    • Leaves www untouched if already provided.
    • Otherwise requires simboard.enabled = True and infers www via infer_simboard_www; raises a clear error if www is empty and SimBoard is not enabled.
  • _launch_scripts now runs the simboard config-hook bundle alongside other predefined bundles, before climo tasks.

Docs (docs/source/parameters.rst)

  • Documents the two new [simboard] parameters.
  • Documents the new www inference rule for the top-level www parameter, including the three failure/success cases (inferred when enabled, error when not enabled, error when Mache lacks web_portal.base_path).
  • Fixes an unrelated typo (configuraitonconfiguration).

Tests

  • tests/test_sections.py: adds expected defaults for the new [simboard] section.
  • tests/test_zppy_main.py (new): comprehensive coverage including:
    • www inference for both production and development simulation types.
    • Path normalization (trailing slash, whitespace).
    • simboard_enabled parsing across bool/string/invalid inputs.
    • Explicit www is preserved even when SimBoard is enabled.
    • Error raised when www is empty and SimBoard is disabled.
    • Error raised when simulation_type = "none" while enabled.
    • Errors raised when Mache's web_portal.base_path is missing or empty.
    • Rejection of subsections under [simboard].
    • Rejection of invalid simulation_type values via ConfigObj validation.

Behavior notes

  • Backward compatible: if www is set explicitly, behavior is unchanged (aside from also validating simulation_type isn't "none" when enabled = True).
  • If www is omitted and SimBoard is not enabled, zppy now raises an error (previously this was enforced structurally by the config spec requiring www).

Select one: This pull request is...

  • a bug fix: increment the patch version
  • a small improvement: increment the minor version
  • a new feature: increment the minor version
  • an incompatible (non-backwards compatible) API change: increment the major version

Small Change

  • To merge, I will use "Squash and merge". That is, this change should be
    a single commit.
  • Logic: I have visually inspected the entire pull request myself.
  • Pre-commit checks: All the pre-commits checks have passed.

@forsyth2 forsyth2 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomvothecoder I had Copilot draft an initial diff for resolving #832, based on notes from our meeting today. I've added some review comments below, including 3 design decision questions for you. Thanks!

Comment thread docs/source/parameters.rst Outdated

* If ``reference_data_path`` (the path to the reference data) is undefined, assume it is the ``diagnostics_base_path`` from Mache plus ``/observations/Atm/climatology/``. (So, it is important to change this for model-vs-model runs).

For the top-level ``www`` parameter:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: these doc changes will be overwritten by the changes coming soon in #839. That PR should be updated if this PR merges first.

Comment thread zppy/defaults/default.ini
www = string
# Leave blank to infer `<web_portal base_path>/simboard/<simboard_type>/`
# when `infer_path_parameters = True`
www = string(default="")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design decision: How do we want users to specify they want to use the SimBoard paths? Is leaving www blank a sufficient method?

Or should we have an explicit "use_simboard" parameter? In some sense, the new simboard_type parameter is such a parameter.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think change makes sense, where www is an optional parameter with a default blank value that gets inferred to SimBoard paths. We'll just need to add a clear logger message and update zppy docs to communicate this new behavior. This would not be a breaking change, but users should be aware of it if they want to start defaulting to SimBoard paths to display their diagnostics on SimBoard.

@chengzhuzhang Thoughts?

Comment thread zppy/defaults/default.ini Outdated
# Reservation -- if you have access to a node reservation, specify it with this parameter.
reservation = string(default="")
# Which SimBoard namespace to use when inferring `www`
simboard_type = option("prod", "dev", default="prod")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a "none" option too.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are going to work with the SimBoard team to determine the values for simboard_type. I'll follow up here after we do this.

@tomvothecoder tomvothecoder Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative based on Jill's preference for generic naming: simulation_type, run_type, diag_type, etc.

Comment thread zppy/__main__.py Outdated
simboard_type = config["default"]["simboard_type"]
web_portal_base_path = machine_info.config.get("web_portal", "base_path")
config["default"]["www"] = (
f"{web_portal_base_path}/simboard/{simboard_type}/"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design decision: Is this the web portal base path we want? (Remember, the URL is deterministic based on the base path).

Do we want to include some sort of $USER directory? NERSC has the interesting first_letter/full_username structure. I believe Compy has stricter permissions and won't allow new subdirectories outside the user directories unless explicitly requested -- I suppose we could have a simboard directory at the same level as all the user subdirs.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks right to me. @chengzhuzhang can provide comment too.

The www structure could look like {web_portal_base_path}/simboard/{simboard_type}/{hpc_username}/{case_name}. Example: {web_portal_base_path}/simboard/production/ac.tvo/v3.LR.historical.

We are going to work with the SimBoard team to determine the values for simboard_type.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we can decide later with the user group on these details. I personally prefer more generic names:
{web_portal_base_path}/simboard - >{web_portal_base_path}/diags_archive
simboard_type -> simulation_type

@tomvothecoder tomvothecoder Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with generic names too. It makes sense if we don't want to tie parameters and directory names to only one tool like SimBoard. This makes it clear that the output is tool-agnostic.

PACE employs generic naming for its output directories, including performance_archive, OLD_PERF, etc.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can decide later with the user group on these details

Do you have an idea of when that would be? I just want to make sure I can get this merged by your deadline. Or is this prototype PR good enough to use for now?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@forsyth2 We have a SimBoard meeting next Tues and will discuss this. The deadline for diagnostics is flexible and can be pushed a few weeks if needed.

Comment thread docs/source/parameters.rst Outdated
For the top-level ``www`` parameter:

* If ``www`` is undefined and ``infer_path_parameters = True``, assume it is ``<web_portal base_path>/simboard/<simboard_type>/``.
* If ``www`` is undefined and ``infer_path_parameters = False``, ``zppy`` will raise an error.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design decision: should we do the same for output?

Note that output isn't nearly as standardized. Web portal base path works because there's exactly one path prefix that gets posted online on the web portal base url. It sounds like SimBoard is most interested in the URL though, considering #836 added an explicit diagnostics_url line in the new provenance settings file.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what output is?

I think SimBoard will only need to scan the deterministic path prefix and extract the web portal base url (diagnostics_url).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

output is sort of the staging area. It contains the output of NCO and e3sm_to_cmip for instance. It also contains everything about the zppy run -- the bash scripts, settings, job outputs, etc.

www is the file path that (if actually on a proper web server path) will be served to a web URL. Visual output (e.g., from e3sm_diags, mpas_analysis) goes here.

So, if SimBoard only cares about URLs, www is the only one that matters. If it also cares about data file paths, output would be useful.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for clarifying. I'll discuss with Jill and other SimBoard team members to see if output is useful or if www for the diagnostics viewer is all that is needed.

@chengzhuzhang
chengzhuzhang self-requested a review June 24, 2026 21:14
@tomvothecoder

Copy link
Copy Markdown
Collaborator

@forsyth2 Thanks for opening this PR so quickly. I replied to some of your comments above and tagged Jill for input.

@tomvothecoder

tomvothecoder commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

@chengzhuzhang and @forsyth2 here is my proposed design based on the SimBoard team meeting.

Zppy diagnostic directory structure

I think zppy should publish SimBoard-compatible diagnostics under one bounded archive root:

<WEB_ROOT>/diagnostics_archive/
  production/
  development/

This gives SimBoard one narrow discovery target, avoids broad scans across unrelated web content, and keeps production and development output separated under one common root. Directory layout would be used for discovery only; provenance.settings under each diagnostic output directory would remain authoritative for classification metadata.

Zppy config

For config, I think this should be explicit and opt-in via a [simboard] section, rather than inferred from generic path-inference behavior. SimBoard publishing should depend only on simboard.enabled=True plus an empty www.

If infer_path_parameters is only being used for SimBoard publishing, I think we should remove it from this flow. It could confuse users because it combines generic path inference with SimBoard-specific behavior by inferring diagnostic archive paths using mache.

Expected behavior:

simboard.enabled www Behavior
False any zppy does nothing SimBoard-specific.
True empty Infer the SimBoard archive path from mache.
True set Use www as the output path and do not override it. simboard.enabled still controls SimBoard-specific metadata and validation.
True empty, but path cannot be inferred Raise a clear configuration error.
[default]
www =                         # Diagnostic web output root. If empty and simboard.enabled=True, infer a SimBoard-compatible archive path from mache.

[simboard]
enabled = False               # Opt in to SimBoard-compatible publishing behavior.
simulation_type = development # Diagnostic classification for SimBoard publishing: production | development.

Let me know what you think. We can discuss more at next week's EZ Meeting too.

@tomvothecoder

Copy link
Copy Markdown
Collaborator

@forsyth2 The team agreed on my design above. Happy to get your thoughts when you return from vacation.

@forsyth2

Copy link
Copy Markdown
Collaborator

Hi @tomvothecoder, thanks for the design.

Checking that each of my design decisions above have been addressed:

Design decision 1

# Leave blank to infer `<web_portal base_path>/simboard/<simboard_type>/`
# when `infer_path_parameters = True`
www = string(default="")

Design decision: How do we want users to specify they want to use the SimBoard paths? Is leaving www blank a sufficient method?

Addressed by:

For config, I think this should be explicit and opt-in via a [simboard] section, rather than inferred from generic path-inference behavior. SimBoard publishing should depend only on simboard.enabled=True plus an empty www.

Expected behavior:

simboard.enabled www Behavior
False any zppy does nothing SimBoard-specific.
True empty Infer the SimBoard archive path from mache.
True set Use www as the output path and do not override it. simboard.enabled still controls SimBoard-specific metadata and validation.
True empty, but path cannot be inferred Raise a clear configuration error.

This makes sense, but adding a new [simboard] section does complicate things a bit. Each section adds its own bash template and Python file. The cloest analog would be the [bundles] section, which like [simboard] isn't so much describing a new task as it is describing how to run other tasks.

In short, this can be implemented, but it's a little bit more overhead. It sounds like that's worth it for clarity to users though.

Design decision 2

    simboard_type = config["default"]["simboard_type"]
    web_portal_base_path = machine_info.config.get("web_portal", "base_path")
    config["default"]["www"] = (
        f"{web_portal_base_path}/simboard/{simboard_type}/"

Design decision: Is this the web portal base path we want? (Remember, the URL is deterministic based on the base path).

Addressed by:

I think zppy should publish SimBoard-compatible diagnostics under one bounded archive root:

<WEB_ROOT>/diagnostics_archive/
 production/
 development/

So, it looks like we just want to change the above to f"{web_portal_base_path}/diagnostics_archive/{simboard_type}/ and set simboard_type = option("production", "development", "none" default="production") (adding "none" for the non-simboard runs) in zppy/defaults/default.ini.

That sounds good to me; do we want to include "simboard" anywhere in the path to be explicit about the structure being for SimBoard? E.g., simboard_diagnostics_archive?

Design decision 3

For the top-level ``www`` parameter:

* If ``www`` is undefined and ``infer_path_parameters = True``, assume it is ``<web_portal base_path>/simboard/<simboard_type>/``.
* If ``www`` is undefined and ``infer_path_parameters = False``, ``zppy`` will raise an error.

Design decision: should we do the same for output?

Not addressed explicitly, but it seems like only www is needed, not output, correct?

@forsyth2

Copy link
Copy Markdown
Collaborator

@copilot Please implement these two additions to this PR:

  1. Add a SimBoard task. The cloest analog would be the [bundles] section, which like [simboard] isn't so much describing a new task as it is describing how to run other tasks. Adding a task typically means adding a corresponding .py file and .bash template.

Expected behavior:

simboard.enabled www Behavior
False any zppy does nothing SimBoard-specific.
True empty Infer the SimBoard archive path from mache.
True set Use www as the output path and do not override it. simboard.enabled still controls SimBoard-specific metadata and validation.
True empty, but path cannot be inferred Raise a clear configuration error.

An example cfg:

[default]
www =                         # Diagnostic web output root. If empty and simboard.enabled=True, infer a SimBoard-compatible archive path from mache.

[simboard]
enabled = False               # Opt in to SimBoard-compatible publishing behavior.
simulation_type = development # Diagnostic classification for SimBoard publishing: production | development.
  1. Change the inferred directory structure when using SimBoard
    simboard_type = config["default"]["simboard_type"]
    web_portal_base_path = machine_info.config.get("web_portal", "base_path")
    config["default"]["www"] = (
        f"{web_portal_base_path}/simboard/{simboard_type}/"

should be updated so that we get something like:

<WEB_ROOT>/diagnostics_archive/
 production/
 development/

That is, f"{web_portal_base_path}/diagnostics_archive/{simboard_type}/ and then in default.ini: simboard_type = option("production", "development", "none" default="production") (adding "none" for the non-simboard runs).

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please implement these two additions to this PR:

  1. Add a SimBoard task. The cloest analog would be the [bundles] section, which like [simboard] isn't so much describing a new task as ...

Addressed in 10b7f2a.

This updates the PR to use an explicit [simboard] section/task hook with enabled and simulation_type, infers empty www only when SimBoard publishing is enabled, switches the inferred archive root to diagnostics_archive/<simulation_type>/, and updates the related validation, docs, and unit coverage.

Copilot AI requested a review from forsyth2 July 22, 2026 00:51

@forsyth2 forsyth2 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing the diff from the last 7 commits, added by the latest call to Copilot.

✅ Add a SimBoard task.
✅ Change the inferred directory structure when using SimBoard.

Comment thread zppy/defaults/default.ini
# Where the post-processing visuals should go (to be viewed online)
# Leave blank to infer `<web_portal base_path>/simboard/<simboard_type>/`
# when `infer_path_parameters = True`
# Leave blank to infer `<web_portal base_path>/diagnostics_archive/<simulation_type>/`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think we should make it something like simboard_diagnostics_archive instead.

Comment thread zppy/__main__.py
Comment on lines +280 to +286
if not simboard_enabled(config):
raise ValueError(
"www is empty. Provide [default] www or set `enabled = True` in "
"the [simboard] section to infer a SimBoard-compatible "
"diagnostics_archive path. Note: inference requires "
"web_portal.base_path in Mache configuration."
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block implements:

Expected behavior:

simboard.enabled www Behavior
False any zppy does nothing SimBoard-specific.

Comment thread zppy/simboard.py
def infer_simboard_www(machine_info: MachineInfo, config: ConfigObj) -> str:
simulation_type = config["simboard"]["simulation_type"]
try:
web_portal_base_path = machine_info.config.get("web_portal", "base_path")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line implements:

Expected behavior:

simboard.enabled www Behavior
True empty Infer the SimBoard archive path from mache.

Comment thread zppy/simboard.py
Comment on lines +78 to +83
except (NoSectionError, NoOptionError) as exc:
raise ValueError(
f"www is empty and simboard.enabled is True, but machine "
f"'{machine_info.machine}' has no web_portal.base_path in mache; "
"cannot infer a diagnostics_archive path."
) from exc

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block implements:

Expected behavior:

simboard.enabled www Behavior
True empty, but path cannot be inferred Raise a clear configuration error.

Comment thread zppy/simboard.py
Comment on lines +85 to +91
web_portal_base_path = normalize_web_portal_base_path(web_portal_base_path)
if web_portal_base_path == "":
raise ValueError(
f"www is empty and simboard.enabled is True, but machine "
f"'{machine_info.machine}' has an empty web_portal.base_path in "
"mache; cannot infer a diagnostics_archive path."
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block also implements:

Expected behavior:

simboard.enabled www Behavior
True empty, but path cannot be inferred Raise a clear configuration error.

Comment thread zppy/simboard.py Outdated
Comment on lines +93 to +100
inferred_www = (
f"{web_portal_base_path}/diagnostics_archive/{simulation_type}/"
)
logger.info(
"Inferred www=%s from mache web_portal.base_path because "
"simboard.enabled is True.",
inferred_www,
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block finishes the implementation of

Expected behavior:

simboard.enabled www Behavior
True empty Infer the SimBoard archive path from mache.

Comment thread zppy/__main__.py
Comment on lines 277 to 278
if config["default"]["www"] != "":
return

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block implements:

Expected behavior:

simboard.enabled www Behavior
True set Use www as the output path and do not override it. simboard.enabled still controls SimBoard-specific metadata and validation.

Comment thread zppy/simboard.py Outdated
Comment on lines +93 to +94
inferred_www = (
f"{web_portal_base_path}/diagnostics_archive/{simulation_type}/"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block implements: f"{web_portal_base_path}/diagnostics_archive/{simboard_type}/"

Comment thread zppy/defaults/default.ini
enabled = boolean(default=False)
# Use "none" only when SimBoard publishing is disabled.
# Default to "production" so enabled configs can opt in without overriding it.
simulation_type = option("production", "development", "none", default="production")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line implements simboard_type = option("production", "development", "none" default="production")

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the top-level www output path configurable as “optional” by defaulting it to an empty string and introducing a SimBoard-oriented configuration hook that can infer www from Mache’s web_portal.base_path. It fits into zppy’s existing parameter inference/validation flow by extending default.ini defaults and performing early parameter determination in zppy.__main__.

Changes:

  • Added a new config-only [simboard] task hook and helpers to validate SimBoard settings and infer www from Mache (zppy/simboard.py).
  • Changed config defaults so [default] www defaults to "", and added a new [simboard] section with enabled and simulation_type (zppy/defaults/default.ini).
  • Wired www inference + SimBoard validation into startup parameter determination, and added unit tests + docs updates (zppy/__main__.py, tests/*, docs/*).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
zppy/simboard.py Adds SimBoard config validation and www inference from web_portal.base_path.
zppy/defaults/default.ini Defaults www to empty string and introduces [simboard] defaults/validation.
zppy/__main__.py Applies SimBoard validation and infers www during parameter determination; registers simboard() in launch flow.
tests/test_zppy_main.py Adds unit tests for www inference, SimBoard enabled parsing, and configspec validation.
tests/test_sections.py Updates expected config sections to include [simboard].
docs/source/parameters.rst Documents new SimBoard parameters and www defaulting/inference behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread zppy/__main__.py
Comment thread zppy/simboard.py Outdated
Comment on lines +93 to +95
inferred_www = (
f"{web_portal_base_path}/diagnostics_archive/{simulation_type}/"
)
Comment thread docs/source/parameters.rst Outdated
Comment on lines +75 to +79
For the top-level ``www`` parameter:

* If ``www`` is undefined and ``[simboard] enabled = True``, assume it is ``<web_portal base_path>/diagnostics_archive/<simulation_type>/``.
* If ``www`` is undefined and ``[simboard] enabled = False``, ``zppy`` will raise an error.
* If ``www`` is undefined and ``[simboard] enabled = True`` but Mache does not provide ``web_portal.base_path``, ``zppy`` will raise an error.
Comment thread zppy/defaults/default.ini
Comment on lines 108 to +111
# Where the post-processing visuals should go (to be viewed online)
# NOTE: no default, must be provided by user
www = string
# Leave blank to infer `<web_portal base_path>/diagnostics_archive/<simulation_type>/`
# when `[simboard] enabled = True`
www = string(default="")
@forsyth2

forsyth2 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Remaining action items:

  • Address Copilot's review comments
  • Rebase & resolve conflicts
  • Confirm completed design with Tom
  • Add integration test cfg that uses SimBoard setup, and run that test cfg

@tomvothecoder

Copy link
Copy Markdown
Collaborator

Thanks for the updates @forsyth2.

This makes sense, but adding a new [simboard] section does complicate things a bit. Each section adds its own bash template and Python file. The cloest analog would be the [bundles] section, which like [simboard] isn't so much describing a new task as it is describing how to run other tasks.

In short, this can be implemented, but it's a little bit more overhead. It sounds like that's worth it for clarity to users though.

I agree, adding the [simboard] section is worth the clarity.

That sounds good to me; do we want to include "simboard" anywhere in the path to be explicit about the structure being for SimBoard? E.g., simboard_diagnostics_archive?

We can keep it generic since SimBoard is a consumer of the archive rather than the owner. Similarly, we'd follow the same model where E3SM simulations output performance/timing metadata to a generic performance_archive directory that PACE consumes.

Not addressed explicitly, but it seems like only www is needed, not output, correct?

I forgot to discuss this with the team. I think for now we can focus on www until somebody brings up the need to view output.

@forsyth2

Copy link
Copy Markdown
Collaborator

Sounds good, thanks @tomvothecoder!

@forsyth2 forsyth2 changed the title Infer empty www from SimBoard defaults Add SimBoard-compatible www inference via a new [simboard] config section Jul 22, 2026
@forsyth2

Copy link
Copy Markdown
Collaborator

It looks like the Copilot review got confused by the un-updated PR description. I've had Claude write an updated description for the PR and pasted it in above. I also included Tom's expected behavior table. Claude also suggested the new title: "Add SimBoard-compatible www inference via a new [simboard] config section".

For reference:

Pasted content

Summary

Adds an opt-in [simboard] configuration section that lets zppy infer the [default] www path automatically instead of requiring users to set it explicitly. This targets SimBoard-compatible publishing, where the diagnostics archive path can be derived from Mache's web_portal.base_path.

Expected behavior:

simboard.enabled www Behavior
False any zppy does nothing SimBoard-specific.
True empty Infer the SimBoard archive path from mache.
True set Use www as the output path and do not override it. simboard.enabled still controls SimBoard-specific metadata and validation.
True empty, but path cannot be inferred Raise a clear configuration error.

Changes

New [simboard] config section (zppy/defaults/default.ini)

  • enabled (bool, default False): opts in to SimBoard-compatible publishing.
  • simulation_type (option: production | development | none, default production): selects the archive classification used when inferring www.
  • [default] www no longer requires an explicit value (string(default="") instead of a bare string), since it can now be inferred.

New module zppy/simboard.py

  • simboard(...): a configuration-only task hook (no HPC job), analogous to [bundle], that validates the [simboard] section has no subsections.
  • simboard_enabled(config): parses enabled from bool or "true"/"false" strings (case-insensitive), raising ValueError on anything else.
  • validate_simboard_config(config): rejects simulation_type = "none" whenever enabled = True.
  • normalize_web_portal_base_path(...): strips whitespace and trailing slashes.
  • infer_simboard_www(machine_info, config): builds <web_portal base_path>/diagnostics_archive/<simulation_type>/, raising a descriptive ValueError if Mache has no (or an empty) web_portal.base_path for the current machine.

zppy/__main__.py

  • _determine_parameters now calls a new _set_default_www helper, which:
    • Always runs validate_simboard_config (so simulation_type is checked even when www is already explicitly set).
    • Leaves www untouched if already provided.
    • Otherwise requires simboard.enabled = True and infers www via infer_simboard_www; raises a clear error if www is empty and SimBoard is not enabled.
  • _launch_scripts now runs the simboard config-hook bundle alongside other predefined bundles, before climo tasks.

Docs (docs/source/parameters.rst)

  • Documents the two new [simboard] parameters.
  • Documents the new www inference rule for the top-level www parameter, including the three failure/success cases (inferred when enabled, error when not enabled, error when Mache lacks web_portal.base_path).
  • Fixes an unrelated typo (configuraitonconfiguration).

Tests

  • tests/test_sections.py: adds expected defaults for the new [simboard] section.
  • tests/test_zppy_main.py (new): comprehensive coverage including:
    • www inference for both production and development simulation types.
    • Path normalization (trailing slash, whitespace).
    • simboard_enabled parsing across bool/string/invalid inputs.
    • Explicit www is preserved even when SimBoard is enabled.
    • Error raised when www is empty and SimBoard is disabled.
    • Error raised when simulation_type = "none" while enabled.
    • Errors raised when Mache's web_portal.base_path is missing or empty.
    • Rejection of subsections under [simboard].
    • Rejection of invalid simulation_type values via ConfigObj validation.

Behavior notes

  • Backward compatible: if www is set explicitly, behavior is unchanged (aside from also validating simulation_type isn't "none" when enabled = True).
  • If www is omitted and SimBoard is not enabled, zppy now raises an error (previously this was enforced structurally by the config spec requiring www).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread tests/test_zppy_main.py
Comment on lines +189 to +203
def test_determine_parameters_requires_inferable_web_root() -> None:
config = _base_config()
config["simboard"]["enabled"] = True
machine_info = _fake_machine_info()
machine_info.config.remove_option("web_portal", "base_path")

with pytest.raises(
ValueError,
match=(
"www is empty and simboard.enabled is True, but machine 'pm-cpu' "
"has no web_portal.base_path in mache; cannot infer a "
"diagnostics_archive path."
),
):
_determine_parameters(machine_info, config)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

base_path will always be available if the machine is defined in Mache. This probably isn't needed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only comes up in the tests because of the fake machine info used. That's the cause of the build error FAILED tests/test_zppy_main.py::test_determine_parameters_requires_inferable_web_root - configparser.NoOptionError: No option 'base_path' in section: 'web_portal'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit Fix NoOptionError crash before SimBoard www inference. The web_portal.base_path and web_portal.base_url reads in _determine_parameters() are now wrapped in try/except blocks that catch NoSectionError/NoOptionError and fall back to "". This lets the NoOptionError propagate to infer_simboard_www(), which already has the proper handler to raise the intended ValueError with the correct message.

Comment thread docs/source/parameters.rst Outdated
@forsyth2
forsyth2 force-pushed the copilot/update-default-www-and-simboard-type branch from 10b7f2a to ee45ff1 Compare July 23, 2026 00:34
Wrap `web_portal.base_path` and `web_portal.base_url` reads in
`_determine_parameters()` with try/except to catch
`NoSectionError`/`NoOptionError`, defaulting to `""`. This lets
the `NoOptionError` be handled properly downstream in
`infer_simboard_www()`, which raises the intended `ValueError`
when `www` is empty and `simboard.enabled` is True.

Fixes `test_determine_parameters_requires_inferable_web_root`
which was failing with `configparser.NoOptionError` before
reaching the SimBoard error-handling code.
Copilot AI requested a review from forsyth2 July 24, 2026 18:00
@forsyth2

Copy link
Copy Markdown
Collaborator

@copilot I've rebased this branch off the latest main, which includes updated docs. Can you please add a commit updating the relevant docs to discuss the new simboard section? Do not update the PR description though.

- Add docs/source/user_guide/tasks/simboard.rst describing
  the [simboard] section, its expected behavior table,
  a configuration example, and its parameters.
- Add simboard to the tasks index (list and toctree).
- Update parameters.rst: www is now optional (inferred when
  simboard.enabled=True); add a SimBoard section parameters
  table at the end.

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot I've rebased this branch off the latest main, which includes updated docs. Can you please add a commit updating the relevant docs to discuss the new simboard section? Do not update the ...

Done in the latest commit. Added docs/source/user_guide/tasks/simboard.rst with the expected-behavior table, a config example, and the enabled/simulation_type parameter descriptions. Updated the tasks index and parameters.rst to reflect that www is now optional (with a note pointing to the simboard task page), and added a [simboard] section parameters table at the end of parameters.rst.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Standardize production diagnostics output location for SimBoard ingestion

5 participants