diff --git a/QUICKSTART.md b/QUICKSTART.md index 0412cd6..c2d6d21 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -22,27 +22,26 @@ The notebook is the authoring entry point for: ## 3) Convert notebook spec to TOML Export the notebook semantics into TOML: ```bash -uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/spec_black_scholes.toml --overwrite +uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/black_scholes_blueprint.toml --overwrite ``` - -## 4) Bridge spec TOML to runtime TOML -Generate an executable pricing config from the notebook spec artefact: +## 4) Bridge blueprint TOML to pricing TOML +Generate an executable pricing config from the notebook blueprint artefact: ```bash -uv run pdealchemy spec-to-runtime-toml examples/notebooks/spec_black_scholes.toml --output examples/notebooks/spec_black_scholes.runtime.toml --overwrite +uv run pdealchemy spec-to-runtime-toml examples/notebooks/black_scholes_blueprint.toml --output examples/notebooks/black_scholes_pricing.toml --overwrite ``` ## 5) Validate the equation library Run constrained LaTeX validation for equations in `library/` together with runtime schema checks: ```bash -uv run pdealchemy validate examples/notebooks/spec_black_scholes.runtime.toml --equation-library library +uv run pdealchemy validate examples/notebooks/black_scholes_pricing.toml --equation-library library ``` ## 6) Run baseline pricing and explain outputs Use the bridged runtime config for pricing and explainability checks: ```bash -uv run pdealchemy validate examples/notebooks/spec_black_scholes.runtime.toml --analytical --tolerance 0.75 -uv run pdealchemy price examples/notebooks/spec_black_scholes.runtime.toml -uv run pdealchemy explain examples/notebooks/spec_black_scholes.runtime.toml --format markdown +uv run pdealchemy validate examples/notebooks/black_scholes_pricing.toml --analytical --tolerance 0.75 +uv run pdealchemy price examples/notebooks/black_scholes_pricing.toml +uv run pdealchemy explain examples/notebooks/black_scholes_pricing.toml --format markdown ``` ## 7) Optional: run the full baseline chain in one command diff --git a/README.md b/README.md index 8c4b90c..b68328f 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ uv run pdealchemy validate path/to/config.toml uv run pdealchemy explain path/to/config.toml --format markdown uv run pdealchemy validate path/to/config.toml --analytical --tolerance 0.75 uv run pdealchemy validate path/to/config.toml --equation-library library -uv run pdealchemy spec-to-runtime-toml path/to/spec.toml --output path/to/runtime.toml --overwrite +uv run pdealchemy spec-to-runtime-toml path/to/spec.toml --output path/to/pricing.toml --overwrite uv run pdealchemy price path/to/config.toml ``` @@ -171,11 +171,11 @@ PDEAlchemy also supports notebook-first specification authoring with semantic ce Convert a specification notebook into TOML: ```bash -uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/spec_black_scholes.toml --overwrite +uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/black_scholes_blueprint.toml --overwrite ``` Bridge spec TOML to executable runtime TOML: ```bash -uv run pdealchemy spec-to-runtime-toml examples/notebooks/spec_black_scholes.toml --output examples/notebooks/spec_black_scholes.runtime.toml --overwrite +uv run pdealchemy spec-to-runtime-toml examples/notebooks/black_scholes_blueprint.toml --output examples/notebooks/black_scholes_pricing.toml --overwrite ``` Or use just recipes: diff --git a/docs/black_scholes_first_workflow.md b/docs/black_scholes_first_workflow.md index 5ce264f..940383d 100644 --- a/docs/black_scholes_first_workflow.md +++ b/docs/black_scholes_first_workflow.md @@ -38,12 +38,12 @@ This catches: ## 4) Notebook-driven spec and runtime bridge baseline Validate the notebook-to-TOML path, then bridge to executable runtime TOML. -- `uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/spec_black_scholes.toml --overwrite` -- `uv run pdealchemy spec-to-runtime-toml examples/notebooks/spec_black_scholes.toml --output examples/notebooks/spec_black_scholes.runtime.toml --overwrite` -- `uv run pdealchemy validate examples/notebooks/spec_black_scholes.runtime.toml --equation-library library` -- `uv run pdealchemy validate examples/notebooks/spec_black_scholes.runtime.toml --analytical --tolerance 0.75` -- `uv run pdealchemy price examples/notebooks/spec_black_scholes.runtime.toml` -- `uv run pdealchemy explain examples/notebooks/spec_black_scholes.runtime.toml --format markdown` +- `uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/black_scholes_blueprint.toml --overwrite` +- `uv run pdealchemy spec-to-runtime-toml examples/notebooks/black_scholes_blueprint.toml --output examples/notebooks/black_scholes_pricing.toml --overwrite` +- `uv run pdealchemy validate examples/notebooks/black_scholes_pricing.toml --equation-library library` +- `uv run pdealchemy validate examples/notebooks/black_scholes_pricing.toml --analytical --tolerance 0.75` +- `uv run pdealchemy price examples/notebooks/black_scholes_pricing.toml` +- `uv run pdealchemy explain examples/notebooks/black_scholes_pricing.toml --format markdown` ## 5) Optional one-command baseline run - `just bs-e2e` diff --git a/docs/output_specification.md b/docs/output_specification.md index e3ea565..1823dd3 100644 --- a/docs/output_specification.md +++ b/docs/output_specification.md @@ -4,14 +4,14 @@ This document defines expected output artefacts, content, and format options for ## Scope The current specification focuses on the canonical Black-Scholes baseline path: - source notebook: `examples/notebooks/spec_black_scholes.py` -- spec TOML: generated via `notebook-to-toml` -- runtime TOML: generated via `spec-to-runtime-toml` +- blueprint TOML: generated via `notebook-to-toml` +- pricing TOML: generated via `spec-to-runtime-toml` ## Core artefacts Each run should produce, or be able to produce, the following artefacts. ### 1) Specification artefact -- **Artefact**: spec TOML +- **Artefact**: blueprint TOML - **Purpose**: semantic representation of the notebook specification - **Minimum content**: - metadata title @@ -22,7 +22,7 @@ Each run should produce, or be able to produce, the following artefacts. - rate/volatility references ### 2) Runtime artefact -- **Artefact**: runtime pricing TOML +- **Artefact**: pricing TOML - **Purpose**: executable schema-conformant config for `validate`, `price`, and `explain` - **Minimum content**: - `[process]` with state variables, parameters, drift, diffusion @@ -101,10 +101,10 @@ Recommended output formats: ## Baseline command chain ```bash -uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/spec_black_scholes.toml --overwrite -uv run pdealchemy spec-to-runtime-toml examples/notebooks/spec_black_scholes.toml --output examples/notebooks/spec_black_scholes.runtime.toml --overwrite -uv run pdealchemy validate examples/notebooks/spec_black_scholes.runtime.toml --equation-library library -uv run pdealchemy validate examples/notebooks/spec_black_scholes.runtime.toml --analytical --tolerance 0.75 -uv run pdealchemy price examples/notebooks/spec_black_scholes.runtime.toml -uv run pdealchemy explain examples/notebooks/spec_black_scholes.runtime.toml --format markdown +uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/black_scholes_blueprint.toml --overwrite +uv run pdealchemy spec-to-runtime-toml examples/notebooks/black_scholes_blueprint.toml --output examples/notebooks/black_scholes_pricing.toml --overwrite +uv run pdealchemy validate examples/notebooks/black_scholes_pricing.toml --equation-library library +uv run pdealchemy validate examples/notebooks/black_scholes_pricing.toml --analytical --tolerance 0.75 +uv run pdealchemy price examples/notebooks/black_scholes_pricing.toml +uv run pdealchemy explain examples/notebooks/black_scholes_pricing.toml --format markdown ``` diff --git a/docs/validation_strategy.md b/docs/validation_strategy.md index e6da1f5..2a7387d 100644 --- a/docs/validation_strategy.md +++ b/docs/validation_strategy.md @@ -63,8 +63,8 @@ Start from the simplest deterministic baseline and add complexity incrementally. - `uv run pdealchemy validate examples/vanilla_european_call.toml --equation-library library` 4. Notebook-to-TOML baseline check -- `uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/spec_black_scholes.toml --overwrite` -- `uv run pdealchemy validate examples/notebooks/spec_black_scholes.toml` +- `uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/black_scholes_blueprint.toml --overwrite` +- `uv run pdealchemy validate examples/notebooks/black_scholes_blueprint.toml` 5. Only then move to richer routes - market curve/surface example (`examples/vanilla_market_curve_surface.toml`) diff --git a/examples/notebooks/black_scholes_results.py b/examples/notebooks/black_scholes_results.py index c39ab4f..355d80a 100644 --- a/examples/notebooks/black_scholes_results.py +++ b/examples/notebooks/black_scholes_results.py @@ -38,7 +38,7 @@ def _(): def _(create_notebook_report_controls, mo, render_notebook_report_controls): controls = create_notebook_report_controls( mo, - runtime_toml_default="examples/notebooks/spec_black_scholes.runtime.toml", + runtime_toml_default="examples/notebooks/black_scholes_pricing.toml", equation_library_default="library", ) render_notebook_report_controls( diff --git a/examples/notebooks/spec_black_scholes_with_results.py b/examples/notebooks/spec_black_scholes_with_results.py index b15dc85..21eb781 100644 --- a/examples/notebooks/spec_black_scholes_with_results.py +++ b/examples/notebooks/spec_black_scholes_with_results.py @@ -148,7 +148,7 @@ def output_controls( ): controls = create_notebook_report_controls( mo, - runtime_toml_default="examples/notebooks/spec_black_scholes.runtime.toml", + runtime_toml_default="examples/notebooks/black_scholes_pricing.toml", equation_library_default="library", ) render_notebook_report_controls( diff --git a/justfile b/justfile index 4143dfb..5889ae3 100644 --- a/justfile +++ b/justfile @@ -41,12 +41,12 @@ notebook-run file="examples/notebooks/price_explorer.py": notebook-check file="examples/notebooks/price_explorer.py": uv run marimo check {{file}} -notebook-to-toml notebook="examples/notebooks/spec_black_scholes.py" output="examples/notebooks/spec_black_scholes.toml": +notebook-to-toml notebook="examples/notebooks/spec_black_scholes.py" output="examples/notebooks/black_scholes_blueprint.toml": uv run pdealchemy notebook-to-toml {{notebook}} --output {{output}} --overwrite -spec-to-runtime-toml spec="examples/notebooks/spec_black_scholes.toml" output="examples/notebooks/spec_black_scholes.runtime.toml": +spec-to-runtime-toml spec="examples/notebooks/black_scholes_blueprint.toml" output="examples/notebooks/black_scholes_pricing.toml": uv run pdealchemy spec-to-runtime-toml {{spec}} --output {{output}} --overwrite -bs-e2e notebook="examples/notebooks/spec_black_scholes.py" spec_output="examples/notebooks/spec_black_scholes.toml" runtime_output="examples/notebooks/spec_black_scholes.runtime.toml" explain_format="markdown": +bs-e2e notebook="examples/notebooks/spec_black_scholes.py" spec_output="examples/notebooks/black_scholes_blueprint.toml" runtime_output="examples/notebooks/black_scholes_pricing.toml" explain_format="markdown": uv run pdealchemy notebook-to-toml {{notebook}} --output {{spec_output}} --overwrite uv run pdealchemy spec-to-runtime-toml {{spec_output}} --output {{runtime_output}} --overwrite uv run pdealchemy validate {{runtime_output}} --equation-library library diff --git a/src/pdealchemy/cli/app.py b/src/pdealchemy/cli/app.py index f0bf63f..f415f86 100644 --- a/src/pdealchemy/cli/app.py +++ b/src/pdealchemy/cli/app.py @@ -114,7 +114,7 @@ def spec_to_runtime_toml( None, "--output", "-o", - help="Output runtime TOML path. Defaults to .runtime.toml.", + help="Output pricing TOML path. Defaults to .pricing.toml.", ), overwrite: bool = typer.Option( False, diff --git a/src/pdealchemy/notebook_reporting.py b/src/pdealchemy/notebook_reporting.py index 862aea0..dfbe055 100644 --- a/src/pdealchemy/notebook_reporting.py +++ b/src/pdealchemy/notebook_reporting.py @@ -114,7 +114,7 @@ class NotebookReportResult: def create_notebook_report_controls( mo: MarimoProtocol, *, - runtime_toml_default: str = "examples/notebooks/spec_black_scholes.runtime.toml", + runtime_toml_default: str = "examples/notebooks/black_scholes_pricing.toml", equation_library_default: str = "library", include_convergence_default: bool = False, ) -> NotebookReportControls: diff --git a/src/pdealchemy/spec_bridge.py b/src/pdealchemy/spec_bridge.py index 5373abb..b1b8c7d 100644 --- a/src/pdealchemy/spec_bridge.py +++ b/src/pdealchemy/spec_bridge.py @@ -301,11 +301,12 @@ def spec_to_runtime_toml_file( ) -> Path: """Write runtime TOML bridged from spec TOML and return the output path.""" rendered = spec_to_runtime_toml_content(spec_toml_path, defaults=defaults) - target_path = ( - output_path - if output_path is not None - else spec_toml_path.with_name(f"{spec_toml_path.stem}.runtime.toml") - ) + default_output_path = spec_toml_path.with_name(f"{spec_toml_path.stem}.pricing.toml") + if spec_toml_path.stem.endswith("_blueprint"): + default_output_path = spec_toml_path.with_name( + f"{spec_toml_path.stem.removesuffix('_blueprint')}_pricing.toml" + ) + target_path = output_path if output_path is not None else default_output_path if target_path.exists() and not overwrite: raise ConfigError( f"Output file already exists: {target_path}", diff --git a/templates/spec_template_examples.md b/templates/spec_template_examples.md index dee0368..582197e 100644 --- a/templates/spec_template_examples.md +++ b/templates/spec_template_examples.md @@ -3,7 +3,7 @@ ## Generate TOML from a specification notebook ```bash -uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/spec_black_scholes.toml --overwrite +uv run pdealchemy notebook-to-toml examples/notebooks/spec_black_scholes.py --output examples/notebooks/black_scholes_blueprint.toml --overwrite ``` ## Equation library file examples diff --git a/tests/notebook/test_notebook_reporting.py b/tests/notebook/test_notebook_reporting.py index a003324..b68d42e 100644 --- a/tests/notebook/test_notebook_reporting.py +++ b/tests/notebook/test_notebook_reporting.py @@ -44,7 +44,7 @@ def vstack(self, blocks: list[object]): def _selection(**overrides): defaults = { - "runtime_toml_path": "examples/notebooks/spec_black_scholes.runtime.toml", + "runtime_toml_path": "examples/notebooks/black_scholes_pricing.toml", "equation_library_path": "library", "compare_backends": True, "include_pricing": True, diff --git a/tests/notebook/test_spec_bridge.py b/tests/notebook/test_spec_bridge.py index c6bfbd0..47d4ce4 100644 --- a/tests/notebook/test_spec_bridge.py +++ b/tests/notebook/test_spec_bridge.py @@ -58,13 +58,22 @@ def test_spec_to_runtime_toml_content_renders_runtime_shape(tmp_path: Path) -> N assert "[numerics.grid]" in rendered -def test_spec_to_runtime_toml_file_writes_default_runtime_suffix(tmp_path: Path) -> None: +def test_spec_to_runtime_toml_file_writes_default_pricing_suffix(tmp_path: Path) -> None: spec_path = tmp_path / "spec_black_scholes.toml" _write_spec_toml(spec_path) + output_path = spec_to_runtime_toml_file(spec_path, overwrite=True) + assert output_path == tmp_path / "spec_black_scholes.pricing.toml" + assert output_path.exists() + + +def test_spec_to_runtime_toml_file_rewrites_blueprint_suffix(tmp_path: Path) -> None: + spec_path = tmp_path / "black_scholes_blueprint.toml" + _write_spec_toml(spec_path) + output_path = spec_to_runtime_toml_file(spec_path, overwrite=True) - assert output_path == tmp_path / "spec_black_scholes.runtime.toml" + assert output_path == tmp_path / "black_scholes_pricing.toml" assert output_path.exists()