From 08186f8be685a6b4baae7b861322ba781e94d398 Mon Sep 17 00:00:00 2001 From: Gregory Paradis Date: Mon, 22 Jun 2026 21:07:18 +0000 Subject: [PATCH] Add FABLE Pyculator onboarding pilot --- .github/ISSUE_TEMPLATE/config.yml | 1 + .../ISSUE_TEMPLATE/fable_validation_run.yml | 60 ++++++++++++ .github/ISSUE_TEMPLATE/setup_problem.yml | 43 +++++++++ .../ISSUE_TEMPLATE/usability_observation.yml | 44 +++++++++ CHANGE_LOG.md | 2 + MANIFEST.in | 2 +- ROADMAP.md | 93 ++++++++++++++++++ docs/guides/fable-pyculator-onboarding.rst | 95 +++++++++++++++++++ docs/index.rst | 1 + .../scenario_output_manifest.example.json | 43 +++++++++ ...e-pyculator-onboarding-validation-pilot.md | 85 +++++++++++++++++ tests/test_examples.py | 12 +++ 12 files changed, 480 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/fable_validation_run.yml create mode 100644 .github/ISSUE_TEMPLATE/setup_problem.yml create mode 100644 .github/ISSUE_TEMPLATE/usability_observation.yml create mode 100644 docs/guides/fable-pyculator-onboarding.rst create mode 100644 examples/fable_2020/scenario_output_manifest.example.json create mode 100644 planning/phase-32-fable-pyculator-onboarding-validation-pilot.md diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..0086358 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: true diff --git a/.github/ISSUE_TEMPLATE/fable_validation_run.yml b/.github/ISSUE_TEMPLATE/fable_validation_run.yml new file mode 100644 index 0000000..a460a43 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/fable_validation_run.yml @@ -0,0 +1,60 @@ +name: FABLE validation run +description: Record a FABLE Calculator Excel-vs-Python validation run. +title: "FABLE validation: " +labels: ["validation", "fable-pyculator"] +body: + - type: markdown + attributes: + value: | + Use this form for sanitized validation notes only. Do not attach raw workbooks, raw validation reports, or private files. + - type: input + id: calculator-provenance + attributes: + label: Calculator provenance + description: Public source, country calculator identifier, version/date, or sanitized local identifier. + placeholder: "Example: Zenodo FABLE Calculator country workbook, downloaded YYYY-MM-DD" + validations: + required: true + - type: textarea + id: scenario-changes + attributes: + label: Scenario changes + description: List the scenario names and changed parameters/cells. Keep private details sanitized. + placeholder: | + Scenario A: + - Parameter/cell: + - Excel value: + - Python value: + validations: + required: true + - type: textarea + id: output-metrics + attributes: + label: Output metrics compared + description: List the key output metrics/cells and why they were selected. + placeholder: | + - Metric/cell: + - Excel output: + - Python output: + - Match status: + validations: + required: true + - type: dropdown + id: comparison-result + attributes: + label: Overall comparison result + options: + - All selected outputs matched. + - Some selected outputs mismatched. + - Python conversion or execution blocked. + - Excel baseline capture blocked. + - Unsure, needs review. + validations: + required: true + - type: textarea + id: notes + attributes: + label: Notes and blockers + description: Include commands, diagnostics, or screenshots only if they are safe to publish. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/setup_problem.yml b/.github/ISSUE_TEMPLATE/setup_problem.yml new file mode 100644 index 0000000..dc30630 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/setup_problem.yml @@ -0,0 +1,43 @@ +name: Setup problem +description: Report a JupyterHub, VSCode, GitHub, virtual environment, or notebook setup problem. +title: "Setup problem: " +labels: ["setup", "fable-pyculator"] +body: + - type: markdown + attributes: + value: | + Use this form when the onboarding path blocks progress. Do not include passwords, tokens, private paths, or raw workbook files. + - type: dropdown + id: environment + attributes: + label: Environment + options: + - Project JupyterHub + - VSCode/code-server + - Local computer + - Other + validations: + required: true + - type: input + id: step-reached + attributes: + label: Step reached + description: Which setup step were you trying to complete? + placeholder: "Example: selecting the .venv notebook kernel" + validations: + required: true + - type: textarea + id: observed-problem + attributes: + label: What happened? + description: Include exact error text if safe. + placeholder: "Describe what you expected and what happened instead." + validations: + required: true + - type: textarea + id: attempted-fixes + attributes: + label: What did you try? + description: List any commands, clicks, reloads, or settings changes you already tried. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/usability_observation.yml b/.github/ISSUE_TEMPLATE/usability_observation.yml new file mode 100644 index 0000000..ece2681 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/usability_observation.yml @@ -0,0 +1,44 @@ +name: Usability observation +description: Record notebook, interface, documentation, or workflow friction. +title: "Usability observation: " +labels: ["usability", "fable-pyculator"] +body: + - type: markdown + attributes: + value: | + Confusion is useful data. Use this form for observations about the workflow, even if nothing is technically broken. + - type: dropdown + id: area + attributes: + label: Area + options: + - Notebook example + - Modelwright wrapper/interface + - DataFrame output + - Documentation + - Scenario editing workflow + - Validation workflow + - Other + validations: + required: true + - type: textarea + id: observation + attributes: + label: Observation + description: What felt confusing, hidden, too technical, or awkward? + validations: + required: true + - type: textarea + id: expected-experience + attributes: + label: Expected experience + description: What did you expect to happen or wish the workflow made easier? + validations: + required: false + - type: textarea + id: suggested-change + attributes: + label: Suggested change + description: Optional. Suggest a documentation, notebook, naming, or interface change. + validations: + required: false diff --git a/CHANGE_LOG.md b/CHANGE_LOG.md index c81edd4..6d2dbc4 100644 --- a/CHANGE_LOG.md +++ b/CHANGE_LOG.md @@ -4,6 +4,8 @@ This file records completed project work in chronological order. ## 2026-06-22 +- Activated Phase 32 on `feature/p32-fable-pyculator-pilot`, created GitHub parent issue #191 and child issues #192 through #197, and scoped the next `0.1.0a7` alpha around FABLE Pyculator HQP onboarding, structured tester issue forms, a validation pilot protocol, and a scenario/output manifest seed format before deeper country-calculator compatibility work. +- Completed the first Phase 32 onboarding and pilot-infrastructure slice by adding a public FABLE Pyculator onboarding guide for the project JupyterHub/code-server workflow, GitHub issue forms for validation runs, usability observations, and setup problems, a planning protocol for Abdulateef's validation checks plus Gloria and Camilla's usability feedback, and a tracked JSON scenario/output manifest seed for sanitized FABLE validation evidence. - Activated Phase 31 on `feature/p31-literate-notebook-examples`, created GitHub parent issue #183 and child issues #187, #185, #186, #184, #188, and #189, and scoped the next `0.1.0a6` alpha around actual known-valid literate `.ipynb` notebook files for the synthetic and generated 2020 FABLE examples, plus matching Sphinx Examples Gallery documentation and validation. - Completed P31.1 through P31.5 by adding real literate Jupyter notebooks under `examples/notebooks/` for the synthetic and generated 2020 FABLE notebook-interface workflows; each notebook includes headings, explanatory markdown, code cells, and stored outputs; Sphinx Examples Gallery pages now link to downloadable `.ipynb` files; and default tests validate notebook JSON, Python kernel metadata, markdown-before-code structure, stored outputs, synthetic notebook execution, and static FABLE notebook validation-boundary output without running the expensive generated FABLE model in default pytest. - Prepared the `0.1.0a6` release candidate by bumping package/import metadata and release docs, passing repo-local bootstrap, Ruff, default `pytest -vv` with `167` passed and `1` benchmark skip, Sphinx warning-as-error docs with notebook downloads copied, Read the Docs theme verification, and `scripts/check_release_artifacts.sh`; the artifact checker built a roughly `56K` wheel and `2.2M` sdist, included the tracked literate notebooks in the sdist, installed the wheel into a clean ignored environment, imported `modelwright 0.1.0a6`, and smoke-tested the CLI. diff --git a/MANIFEST.in b/MANIFEST.in index 29955ee..4c89e84 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1 @@ -recursive-include examples *.ipynb *.md *.py *.xz +recursive-include examples *.ipynb *.json *.md *.py *.xz diff --git a/ROADMAP.md b/ROADMAP.md index 20000ac..940f488 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1040,3 +1040,96 @@ Release result: - CLI help verified from the clean PyPI install. - GitHub Pages docs verified with the Examples Gallery, both notebook example pages, both downloadable `.ipynb` files, and `0.1.0a6` release-deployment content. + +## Current Next Steps + +## Phase 32: FABLE Pyculator Onboarding And Validation Pilot + +GitHub parent issue: #191 + +Active branch: `feature/p32-fable-pyculator-pilot` + +Status: active. + +Goal: turn the current Modelwright humane-interface prototype into a structured onboarding and +validation pilot for Abdulateef, Gloria, and Camilla. The phase should make setup repeatable, make +tester feedback easy to capture, and define an initial FABLE-P validation protocol before deeper +FABLE Calculator compatibility work begins. + +Release target: `modelwright==0.1.0a7`. + +- [x] P32.1 Add FABLE Pyculator HQP onboarding guide. Child issue: #192. + - Status: complete. + - [x] Document JupyterHub login with UBC CWL. + - [x] Document opening VSCode/code-server from JupyterLab. + - [x] Document GitHub authentication and cloning the Modelwright repo. + - [x] Document creating a repo-local `.venv` and selecting it as the notebook kernel. + - [x] Document running the tracked notebook examples. + - [x] Include Basecamp setup-help invitation and source-workbook hygiene. + - [x] Link the guide from the Sphinx docs index. +- [x] P32.2 Add structured tester GitHub issue templates. Child issue: #193. + - Status: complete. + - [x] Add FABLE validation run issue form. + - [x] Add usability observation issue form. + - [x] Add setup problem issue form. + - [x] Leave blank issues enabled. + - [x] Validate issue-template YAML syntax. +- [x] P32.3 Define FABLE-P validation pilot protocol. Child issue: #194. + - Status: complete. + - [x] Define workbook provenance and local artifact rules. + - [x] Define scenario parameter-change recording expectations. + - [x] Define Excel-vs-generated-Python output comparison expectations. + - [x] Define sanitized tracked finding boundaries. + - [x] Keep raw workbooks and raw validation reports ignored under `tmp/`. +- [x] P32.4 Add scenario/output manifest seed format. Child issue: #195. + - Status: complete. + - [x] Define workbook identifier and provenance summary fields. + - [x] Define scenario name and changed input fields. + - [x] Define key output metric fields. + - [x] Define Excel value, Python value, comparison status, and notes fields. + - [x] Keep this as a seed format, not a full validation framework. +- [ ] P32.5 Improve notebook examples from first-user friction. Child issue: #196. + - Status: active. + - [ ] Triage Gloria/Camilla usability observations. + - [ ] Triage Abdulateef validation-run friction. + - [ ] Apply only focused notebook/docs/API-polish changes justified by pilot feedback. + - [ ] Keep unrelated converter compatibility work out of this phase. +- [ ] P32.6 Publish `modelwright==0.1.0a7`. Child issue: #197. + - Status: planned. + - [ ] Confirm P32 onboarding/protocol/template scope and evidence are complete. + - [ ] Bump package/import version and release docs to `0.1.0a7`. + - [ ] Run local release checks, including Ruff, pytest, Sphinx docs, docs theme verification, and + release artifact checks. + - [ ] Open and merge the P32 PR to `main`. + - [ ] Create annotated tag `v0.1.0a7`. + - [ ] Publish through the gated release workflow after maintainer approval. + - [ ] Verify PyPI JSON, clean PyPI install, import version, CLI help, GitHub release, and docs deployment. + +Acceptance boundary: + +- May claim a documented onboarding and validation pilot workflow for FABLE Pyculator testers. +- May claim structured validation and usability feedback can be captured through GitHub issues and + manifest seeds. +- Must not claim arbitrary FABLE country calculator support, production FABLE-P Canada readiness, + stable public API compatibility, or a full scenario automation framework. + +Implementation evidence: + +- Added `docs/guides/fable-pyculator-onboarding.rst` and linked it from the Sphinx guide index. +- Added GitHub issue forms for FABLE validation runs, setup problems, and usability observations. +- Added `planning/phase-32-fable-pyculator-onboarding-validation-pilot.md` with local artifact rules, + validation protocol, usability protocol, and manifest-seed intent. +- Added `examples/fable_2020/scenario_output_manifest.example.json` as a sanitized seed for recording + scenario inputs and selected Excel-vs-Python output comparisons. +- Updated `MANIFEST.in` so JSON example artifacts are included in source distributions. + +Verification evidence: + +- `.venv/bin/python -m pytest -vv tests/test_examples.py` passed with `7` tests. +- `.venv/bin/python -m ruff check .` passed. +- `.venv/bin/python -m pytest` passed with `168` passed and `1` skipped benchmark. +- `.venv/bin/sphinx-build -b html docs _build/html -W` passed and included the FABLE Pyculator + onboarding guide. +- `ruby -e 'require "yaml"; ...'` parsed all GitHub issue-template YAML files successfully. +- `.venv/bin/python` parsed `examples/fable_2020/scenario_output_manifest.example.json` as valid JSON. +- `git diff --check` passed. diff --git a/docs/guides/fable-pyculator-onboarding.rst b/docs/guides/fable-pyculator-onboarding.rst new file mode 100644 index 0000000..8ba29d6 --- /dev/null +++ b/docs/guides/fable-pyculator-onboarding.rst @@ -0,0 +1,95 @@ +FABLE Pyculator Onboarding +========================== + +This guide is for HQP joining the Modelwright/FABLE Pyculator pilot. The immediate goal is to help +new testers run the tracked notebook examples, record validation results, and report usability +friction in a consistent place. + +The FABLE Pyculator is a workflow name for using Modelwright-generated Python models with FABLE +Calculator workbooks. It is not a separate package and it is not a claim that arbitrary FABLE country +calculators are production-ready. + +Start In The Project Dev Environment +------------------------------------ + +Use the project JupyterHub environment: + +.. code-block:: text + + https://fresh01.01101.dev/jupyterhub14/ + +Log in with your UBC CWL. After login, JupyterLab should open a default Launcher tab. + +From that Launcher tab, click **VSCode (code-server)** at the end of the top row of launch buttons. +The JupyterLab interface also works, but VSCode has better built-in support for GitHub +authentication, repository cloning, Python environments, and notebook editing. In JupyterLab, those +steps require more manual shell commands. + +Set Up The Repository In VSCode +------------------------------- + +In VSCode/code-server: + +1. Authenticate VSCode with your GitHub account when prompted. +2. Clone the Modelwright repository from GitHub. +3. Open the cloned repository folder. +4. Open one of the tracked notebooks under ``examples/notebooks/``. +5. Allow VSCode to install the Python and Jupyter extensions if prompted. +6. Create a repository-local virtual environment from the repo root: + + .. code-block:: bash + + python -m venv .venv + .venv/bin/python -m pip install --upgrade pip + .venv/bin/python -m pip install -e '.[dev]' + +7. Select the ``.venv`` Python interpreter as the notebook kernel. +8. Run the notebook cells live. + +If VSCode asks whether it can trust the workspace, approve the repository workspace only if it is the +Modelwright checkout you cloned from the project GitHub repository. + +What To Try First +----------------- + +Start with the Examples Gallery: + +.. code-block:: text + + https://ubc-fresh.github.io/modelwright/examples.html + +Then run the tracked notebooks: + +- ``examples/notebooks/synthetic-notebook-interface.ipynb`` +- ``examples/notebooks/fable-2020-notebook-interface.ipynb`` + +As you go, write down every point where the workflow assumes too much, hides too much, or makes you +wonder what to do next. Those notes are part of the development process. + +Where To Leave Notes +-------------------- + +Use GitHub issues for structured project notes: + +- Use the FABLE validation run form when comparing Excel and generated Python outputs. +- Use the usability observation form when something about the interface, notebook, or documentation is + confusing. +- Use the setup problem form when the dev environment, GitHub authentication, VSCode, ``.venv``, or + notebook kernel setup blocks progress. + +If you want help getting set up, ping Greg in Basecamp and ask for a setup working session. It is also +fine to work through the setup independently and report what was confusing afterward. + +Source Workbook Hygiene +----------------------- + +Raw FABLE Calculator workbooks, downloaded country calculators, generated Python clones, local logs, +and full validation reports should stay as local working material unless the maintainer explicitly +approves a small sanitized tracked artifact. + +Keep local workbook material under ignored ``tmp/`` paths. Do not commit original workbook files to +the Modelwright repository. + +Safe tracked material includes small scripts, cleaned notes, sanitized validation summaries, compact +manifest examples, generated Python outputs that have been explicitly approved for tracking, and +documentation. diff --git a/docs/index.rst b/docs/index.rst index cf1d442..66367c2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,6 +13,7 @@ assemble validation reports. It is not yet a general workbook converter. :caption: Guides guides/quickstart + guides/fable-pyculator-onboarding guides/developer-onboarding guides/workflow-boundaries guides/private-workbooks diff --git a/examples/fable_2020/scenario_output_manifest.example.json b/examples/fable_2020/scenario_output_manifest.example.json new file mode 100644 index 0000000..70bcf63 --- /dev/null +++ b/examples/fable_2020/scenario_output_manifest.example.json @@ -0,0 +1,43 @@ +{ + "schema_name": "modelwright-fable-pyculator-scenario-output-manifest", + "schema_version": 1, + "workbook": { + "identifier": "fable-country-calculator-sanitized-id", + "source": "Public source URL or citation goes here.", + "version": "Workbook version or release date if known.", + "downloaded_on": "YYYY-MM-DD", + "local_workbook_path": "tmp/private-workbooks/; do not commit the workbook." + }, + "scenario": { + "name": "example-scenario", + "description": "Short human-readable summary of the scenario change.", + "changed_inputs": [ + { + "label": "Scenario selection parameter", + "cell_ref": "SCENARIOS selection!A1", + "excel_value": "baseline", + "python_value": "baseline", + "notes": "Use public or sanitized labels only." + } + ] + }, + "outputs": [ + { + "label": "Key output metric", + "cell_ref": "Output sheet!A1", + "unit": "reported unit", + "excel_value": 0.0, + "python_value": 0.0, + "comparison_status": "match", + "absolute_difference": 0.0, + "notes": "Use match, mismatch, blocked, or needs-review." + } + ], + "run": { + "modelwright_commit": "git-commit-sha", + "excel_capture_method": "Manual workbook run or documented local script.", + "python_capture_method": "Modelwright generated-model run or notebook workflow.", + "status": "pass", + "notes": "Sanitized run notes only." + } +} diff --git a/planning/phase-32-fable-pyculator-onboarding-validation-pilot.md b/planning/phase-32-fable-pyculator-onboarding-validation-pilot.md new file mode 100644 index 0000000..c2a757f --- /dev/null +++ b/planning/phase-32-fable-pyculator-onboarding-validation-pilot.md @@ -0,0 +1,85 @@ +# Phase 32 FABLE Pyculator Onboarding And Validation Pilot + +Date: 2026-06-22 + +## Purpose + +Phase 32 turns the current Modelwright humane-interface prototype into a structured pilot workflow +for new HQP testers. The pilot should make setup repeatable, make tester feedback easy to capture, +and define an initial validation protocol before deeper FABLE Calculator compatibility work begins. + +FABLE Pyculator is a workflow name for FABLE Calculator models converted or wrapped through +Modelwright. It is not a package rename and it is not a production-readiness claim. + +## Roles + +- Abdulateef focuses on validation runs across multiple FABLE country calculators. +- Gloria and Camilla focus on usability, interface clarity, notebook workflow, and setup friction. +- Greg triages feedback, keeps the public repository clean, and decides which local artifacts can be + converted into sanitized tracked material. + +## Local Artifact Rules + +Raw country calculators, downloaded workbooks, generated Python clones, local logs, and full +validation reports stay under ignored `tmp/` paths unless the maintainer explicitly approves a small +sanitized tracked artifact. + +Tracked content may include: + +- onboarding documentation; +- issue-template structure; +- sanitized validation summaries; +- compact scenario/output manifest examples; +- package or notebook improvements; +- generated Python outputs only when explicitly approved. + +Tracked content must not include: + +- original FABLE workbook files; +- raw workbook extracts; +- raw validation reports; +- private local paths; +- unpublished workbook details that have not been sanitized. + +## Validation Pilot Protocol + +For each country calculator validation run: + +1. Record calculator provenance in sanitized form: source, country identifier if public, version/date, + and download date. +2. Store the workbook and raw working files under ignored `tmp/`. +3. Choose four or five scenario variants by changing parameters on the scenario selection sheet. +4. Record the changed parameters or cell references, old values, and new values. +5. Capture selected Excel outputs for key metrics such as GHG emissions or other agreed headline + outputs. +6. Convert or run the corresponding generated Python workflow through Modelwright. +7. Apply the same input changes in Python. +8. Compare selected outputs and record exact matches, mismatches, blockers, or uncertainty. +9. File a sanitized GitHub issue using the FABLE validation run form. + +Do not force a validation run through unclear workbook semantics. If the workflow blocks on external +links, unsupported formulas, macros, volatile behavior, or ambiguous scenario controls, record the +blocker instead. + +## Usability Pilot Protocol + +For each usability pass: + +1. Start from the FABLE Pyculator onboarding guide. +2. Log in to the project JupyterHub and open VSCode/code-server. +3. Authenticate to GitHub, clone Modelwright, create `.venv`, select the notebook kernel, and run one + tracked notebook. +4. Record every point where setup, naming, notebook text, scenario mutation, DataFrame output, + provenance, or validation expectations are unclear. +5. File each distinct observation as a GitHub issue using the usability or setup form. + +Usability notes are not side comments. They are pilot evidence that should drive P32.5 refinements. + +## Scenario Manifest Seed + +The seed manifest under `examples/fable_2020/` is a documentation artifact, not a complete validation +framework. Its purpose is to show the minimum structured fields needed to turn manual validation notes +into repeatable evidence later. + +Future work may promote the seed into a typed schema or CLI workflow after pilot feedback proves which +fields are actually useful. diff --git a/tests/test_examples.py b/tests/test_examples.py index 2faaf2a..4adec8b 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -42,6 +42,18 @@ def test_fable_generated_model_archive_is_tracked_and_readable() -> None: assert b"Generated Modelwright model" in prefix +def test_fable_scenario_output_manifest_seed_is_valid() -> None: + manifest_path = ROOT / "examples/fable_2020/scenario_output_manifest.example.json" + payload = json.loads(manifest_path.read_text()) + + assert payload["schema_name"] == "modelwright-fable-pyculator-scenario-output-manifest" + assert payload["schema_version"] == 1 + assert payload["workbook"]["local_workbook_path"].startswith("tmp/") + assert payload["scenario"]["changed_inputs"] + assert payload["outputs"][0]["comparison_status"] == "match" + assert payload["run"]["status"] == "pass" + + def notebook(path: str) -> dict: return json.loads((ROOT / path).read_text())