axiomize-quantum-skills-2.0 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +18 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +15 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +10 -0
- package/.github/SECURITY-AUDIT-NOTE +1 -0
- package/.github/dependabot.yml +14 -0
- package/.github/pypi-release-trigger +2 -0
- package/.github/scripts/advanced_family_release_smoke.py +248 -0
- package/.github/scripts/check_release_contract.py +103 -0
- package/.github/scripts/cli_release_smoke.py +415 -0
- package/.github/scripts/general_model_release_smoke.py +292 -0
- package/.github/scripts/import_contract_smoke.py +121 -0
- package/.github/scripts/platform_wheel_cli_smoke.py +196 -0
- package/.github/scripts/portable_export_release_smoke.py +66 -0
- package/.github/scripts/scientific_stress_gate.py +21 -0
- package/.github/scripts/security_contract_smoke.py +96 -0
- package/.github/scripts/surrogate_release_smoke.py +95 -0
- package/.github/workflows/ci.yml +154 -0
- package/.github/workflows/npm-publish.yml +33 -0
- package/.github/workflows/pages.yml +74 -0
- package/.github/workflows/release.yml +236 -0
- package/CHANGELOG.md +332 -0
- package/CONTRIBUTING.md +60 -0
- package/LICENSE +21 -0
- package/README.md +297 -0
- package/ROADMAP.md +77 -0
- package/SECURITY.md +21 -0
- package/SKILLS.md +23 -0
- package/benchmarks/ideas.json +172 -0
- package/benchmarks/reports/ad-lift-causal.md +295 -0
- package/benchmarks/reports/app-adoption-ceiling.md +283 -0
- package/benchmarks/reports/barista-staffing.md +271 -0
- package/benchmarks/reports/biology-drug-dosing.md +59 -0
- package/benchmarks/reports/biology-predator-prey.md +144 -0
- package/benchmarks/reports/causal-confounding.md +146 -0
- package/benchmarks/reports/causal-training-productivity.md +64 -0
- package/benchmarks/reports/chemistry-batch-yield.md +60 -0
- package/benchmarks/reports/chemistry-catalyst-deactivation.md +57 -0
- package/benchmarks/reports/chemistry-equilibrium.md +145 -0
- package/benchmarks/reports/duopoly-price-cut.md +287 -0
- package/benchmarks/reports/epidemic-threshold.md +292 -0
- package/benchmarks/reports/greenhouse-setpoint.md +247 -0
- package/benchmarks/reports/novel-async-alignment.md +288 -0
- package/benchmarks/reports/novel-telephone-fidelity.md +265 -0
- package/benchmarks/reports/operations-airline-overbooking.md +59 -0
- package/benchmarks/reports/operations-inventory.md +146 -0
- package/benchmarks/reports/physics-heat-conduction.md +143 -0
- package/benchmarks/reports/physics-oscillator-ringdown.md +61 -0
- package/benchmarks/reports/physics-pendulum-drift.md +59 -0
- package/benchmarks/reports/reasoning-ablation.md +38 -0
- package/benchmarks/reports/reasoning-threshold-sweep.md +42 -0
- package/benchmarks/reports/reserve-ruin.md +274 -0
- package/benchmarks/reports/school-rumor-reach.md +231 -0
- package/benchmarks/rubric.md +34 -0
- package/bin/axiomize-quantum.js +2 -0
- package/docs/benchmark-results.md +45 -0
- package/docs/example-gallery.md +63 -0
- package/docs/index.md +15 -0
- package/docs/integrations.md +59 -0
- package/docs/portable-export-example.json +14 -0
- package/docs/portable-export.md +27 -0
- package/docs/publishing-checklist.md +30 -0
- package/docs/report-sample.pdf +0 -0
- package/docs/report-sample.tex +103 -0
- package/docs/security-audit-1.11.2.md +21 -0
- package/docs/security-ci-contract.md +3 -0
- package/docs/security-maintenance.md +3 -0
- package/docs/security-non-goals.md +3 -0
- package/docs/security-release-checklist.md +13 -0
- package/docs/security-versioning.md +3 -0
- package/docs/security.md +27 -0
- package/docs/sir-demo.gif +0 -0
- package/docs/sir-example.png +0 -0
- package/docs/tutorial.md +61 -0
- package/examples/biology-population.md +119 -0
- package/examples/cafe-pricing-war.md +76 -0
- package/examples/chemistry-reaction.md +125 -0
- package/examples/climate-energy.md +20 -0
- package/examples/coffee-shop-staffing.md +98 -0
- package/examples/control-greenhouse.md +80 -0
- package/examples/engineering-control.md +119 -0
- package/examples/epidemic-sir.md +95 -0
- package/examples/finance-portfolio.md +20 -0
- package/examples/fleet-maintenance.md +74 -0
- package/examples/insurance-ruin.md +77 -0
- package/examples/marketing-attribution.md +74 -0
- package/examples/network-rumor.md +76 -0
- package/examples/physics-oscillator.md +123 -0
- package/examples/probability-bayes.md +143 -0
- package/examples/sensor-placement.md +72 -0
- package/examples/startup-growth.md +70 -0
- package/examples/supply-chain-inventory.md +96 -0
- package/index.js +1 -0
- package/mkdocs.yml +14 -0
- package/package.json +1 -0
- package/packs/biology.md +134 -0
- package/packs/chemistry.md +167 -0
- package/packs/climate.md +50 -0
- package/packs/domain-packs.md +20 -0
- package/packs/ecology.md +24 -0
- package/packs/economics.md +24 -0
- package/packs/engineering.md +150 -0
- package/packs/epidemiology.md +27 -0
- package/packs/finance.md +50 -0
- package/packs/operations.md +27 -0
- package/packs/physics.md +121 -0
- package/packs/probability.md +179 -0
- package/packs/project-management.md +24 -0
- package/playground/app.py +149 -0
- package/pyproject.toml +102 -0
- package/requirements-test.txt +29 -0
- package/skills/axiomize/SKILL.md +237 -0
- package/skills/axiomize/adaptive-workflow.md +113 -0
- package/skills/axiomize/archetypes.md +54 -0
- package/skills/axiomize/first-principles.md +78 -0
- package/skills/axiomize/perspectives/agent-based.md +43 -0
- package/skills/axiomize/perspectives/causal-inference.md +33 -0
- package/skills/axiomize/perspectives/control.md +45 -0
- package/skills/axiomize/perspectives/decision-theory.md +80 -0
- package/skills/axiomize/perspectives/demographic.md +51 -0
- package/skills/axiomize/perspectives/deterministic.md +42 -0
- package/skills/axiomize/perspectives/game-theory.md +37 -0
- package/skills/axiomize/perspectives/information-theory.md +34 -0
- package/skills/axiomize/perspectives/network.md +45 -0
- package/skills/axiomize/perspectives/optimization.md +50 -0
- package/skills/axiomize/perspectives/reliability.md +40 -0
- package/skills/axiomize/perspectives/spatial.md +83 -0
- package/skills/axiomize/perspectives/spc.md +73 -0
- package/skills/axiomize/perspectives/stochastic.md +48 -0
- package/skills/axiomize/perspectives/thermodynamic.md +95 -0
- package/skills/axiomize/rigor.md +47 -0
- package/skills/axiomize/templates/assumptions.md +32 -0
- package/skills/axiomize/templates/glossary.md +36 -0
- package/skills/axiomize/templates/parameters.md +35 -0
- package/skills/axiomize/templates/report.md +106 -0
- package/skills/axiomize/templates/subagent-brief.md +61 -0
- package/skills/axiomize/tools/benchmark_runner.py +215 -0
- package/skills/axiomize/tools/check_skill.py +133 -0
- package/skills/axiomize/tools/csv_check.py +127 -0
- package/skills/axiomize/tools/fit.py +394 -0
- package/skills/axiomize/tools/index_reports.py +67 -0
- package/skills/axiomize/tools/parallel_sweep.py +168 -0
- package/skills/axiomize/tools/report_to_latex.py +384 -0
- package/skills/axiomize/tools/validate.py +420 -0
- package/skills/quantum-reasoning/SKILL.md +148 -0
- package/skills/quantum-reasoning/VERSION +1 -0
- package/skills/quantum-reasoning/docs/COMPATIBILITY.md +44 -0
- package/skills/quantum-reasoning/docs/MEASUREMENT.md +135 -0
- package/skills/quantum-reasoning/examples/host-integration.md +57 -0
- package/skills/quantum-reasoning/examples/usage.md +31 -0
- package/src/axiomize/__init__.py +17 -0
- package/src/axiomize/advanced_diagnostics.py +363 -0
- package/src/axiomize/advanced_family_engine.py +1493 -0
- package/src/axiomize/application/__init__.py +5 -0
- package/src/axiomize/application/advanced_services.py +145 -0
- package/src/axiomize/application/general_services.py +286 -0
- package/src/axiomize/application/services.py +310 -0
- package/src/axiomize/application/surrogate_services.py +114 -0
- package/src/axiomize/bayesian/__init__.py +34 -0
- package/src/axiomize/bayesian/diagnostics.py +140 -0
- package/src/axiomize/bayesian/engine_v2.py +195 -0
- package/src/axiomize/bayesian/likelihoods.py +154 -0
- package/src/axiomize/bayesian/mh.py +123 -0
- package/src/axiomize/bayesian/pymc_tool.py +130 -0
- package/src/axiomize/benchmark_suite.py +153 -0
- package/src/axiomize/capabilities.py +87 -0
- package/src/axiomize/causal_engine.py +460 -0
- package/src/axiomize/cli.py +338 -0
- package/src/axiomize/control/__init__.py +5 -0
- package/src/axiomize/control/pid.py +84 -0
- package/src/axiomize/data/__init__.py +5 -0
- package/src/axiomize/data/quality.py +187 -0
- package/src/axiomize/dimensional_engine.py +196 -0
- package/src/axiomize/execution/__init__.py +5 -0
- package/src/axiomize/execution/sandbox.py +192 -0
- package/src/axiomize/extended_export.py +107 -0
- package/src/axiomize/falsification/__init__.py +5 -0
- package/src/axiomize/falsification/engine.py +43 -0
- package/src/axiomize/fitting/__init__.py +11 -0
- package/src/axiomize/fitting/estimator.py +208 -0
- package/src/axiomize/formal/__init__.py +10 -0
- package/src/axiomize/formal/lean_adapter.py +132 -0
- package/src/axiomize/general_engine.py +505 -0
- package/src/axiomize/general_engine_core.py +970 -0
- package/src/axiomize/integrations/__init__.py +9 -0
- package/src/axiomize/integrations/scs_adapter.py +48 -0
- package/src/axiomize/json_safety.py +55 -0
- package/src/axiomize/limits.py +151 -0
- package/src/axiomize/model_ir.py +486 -0
- package/src/axiomize/models/__init__.py +5 -0
- package/src/axiomize/models/candidates.py +55 -0
- package/src/axiomize/network/__init__.py +9 -0
- package/src/axiomize/network/epidemic.py +121 -0
- package/src/axiomize/numerical_verification.py +358 -0
- package/src/axiomize/numerical_verification_v2.py +122 -0
- package/src/axiomize/pde/__init__.py +5 -0
- package/src/axiomize/pde/diffusion.py +80 -0
- package/src/axiomize/portable_export_compat.py +39 -0
- package/src/axiomize/providers/__init__.py +7 -0
- package/src/axiomize/providers/base.py +40 -0
- package/src/axiomize/providers/echo.py +31 -0
- package/src/axiomize/providers/openai_compatible.py +148 -0
- package/src/axiomize/reasoning/__init__.py +39 -0
- package/src/axiomize/reasoning/ablation.py +465 -0
- package/src/axiomize/reasoning/benchmark/README.md +133 -0
- package/src/axiomize/reasoning/benchmark/__init__.py +10 -0
- package/src/axiomize/reasoning/benchmark/cases.jsonl +6 -0
- package/src/axiomize/reasoning/benchmark/evaluate.py +257 -0
- package/src/axiomize/reasoning/benchmark/schemas/case.schema.json +20 -0
- package/src/axiomize/reasoning/benchmark/schemas/comparison.schema.json +64 -0
- package/src/axiomize/reasoning/benchmark/schemas/metadata.schema.json +53 -0
- package/src/axiomize/reasoning/benchmark/schemas/result.schema.json +25 -0
- package/src/axiomize/reasoning/benchmark/validate_submission.py +118 -0
- package/src/axiomize/reasoning/branch_controller.py +261 -0
- package/src/axiomize/reasoning/cli.py +89 -0
- package/src/axiomize/routing/__init__.py +5 -0
- package/src/axiomize/routing/router.py +141 -0
- package/src/axiomize/runs/__init__.py +5 -0
- package/src/axiomize/runs/bundle.py +26 -0
- package/src/axiomize/runs/compare.py +118 -0
- package/src/axiomize/runs/state.py +240 -0
- package/src/axiomize/runtime_guard.py +90 -0
- package/src/axiomize/safe_expression.py +281 -0
- package/src/axiomize/scientific_stress.py +95 -0
- package/src/axiomize/sensitivity/__init__.py +5 -0
- package/src/axiomize/sensitivity/analysis.py +91 -0
- package/src/axiomize/server/__init__.py +5 -0
- package/src/axiomize/server/mcp_server.py +268 -0
- package/src/axiomize/server/rest_server.py +315 -0
- package/src/axiomize/standards_export.py +326 -0
- package/src/axiomize/surrogate.py +501 -0
- package/src/axiomize/tools/__init__.py +5 -0
- package/src/axiomize/tools/autodiff/__init__.py +1 -0
- package/src/axiomize/tools/autodiff/jax_tool.py +122 -0
- package/src/axiomize/tools/base.py +60 -0
- package/src/axiomize/tools/inventory.py +67 -0
- package/src/axiomize/tools/logic/__init__.py +5 -0
- package/src/axiomize/tools/logic/z3_tool.py +275 -0
- package/src/axiomize/tools/numerical/__init__.py +17 -0
- package/src/axiomize/tools/numerical/scipy_tool.py +184 -0
- package/src/axiomize/tools/optimization/__init__.py +6 -0
- package/src/axiomize/tools/optimization/casadi_tool.py +80 -0
- package/src/axiomize/tools/optimization/cvxpy_tool.py +116 -0
- package/src/axiomize/tools/pde/__init__.py +5 -0
- package/src/axiomize/tools/pde/fenics_tool.py +156 -0
- package/src/axiomize/tools/statistics/__init__.py +5 -0
- package/src/axiomize/tools/statistics/statsmodels_tool.py +84 -0
- package/src/axiomize/tools/symbolic/__init__.py +21 -0
- package/src/axiomize/tools/symbolic/sympy_tool.py +146 -0
- package/src/axiomize/uncertainty/__init__.py +9 -0
- package/src/axiomize/uncertainty/quantify.py +96 -0
- package/src/axiomize/v120_runtime.py +97 -0
- package/src/axiomize/validation/__init__.py +5 -0
- package/src/axiomize/validation/cross.py +50 -0
- package/src/axiomize/validation/dimensions.py +198 -0
- package/src/axiomize/validation/ledger.py +250 -0
- package/src/axiomize/validation/provenance.py +41 -0
- package/src/axiomize/validation/status.py +15 -0
- package/src/axiomize/visualization/__init__.py +9 -0
- package/src/axiomize/visualization/plots.py +96 -0
- package/src/axiomize/workflow/__init__.py +26 -0
- package/src/axiomize/workflow/intake.py +128 -0
- package/src/axiomize/workflow/policy.py +247 -0
- package/src/axiomize/workflow/reasoning_adapter.py +72 -0
- package/tests/__init__.py +0 -0
- package/tests/test_adaptive_workflow.py +164 -0
- package/tests/test_advanced_family_engine.py +305 -0
- package/tests/test_audit_hardening_1122.py +73 -0
- package/tests/test_bayesian_likelihoods.py +182 -0
- package/tests/test_benchmark_ideas.py +49 -0
- package/tests/test_benchmark_input_hardening.py +30 -0
- package/tests/test_benchmark_runner.py +55 -0
- package/tests/test_benchmark_suite.py +133 -0
- package/tests/test_cli_output_contract.py +22 -0
- package/tests/test_engine_phase1.py +180 -0
- package/tests/test_engine_phases26.py +283 -0
- package/tests/test_engine_phases710.py +175 -0
- package/tests/test_full_runtime_hardening.py +109 -0
- package/tests/test_gap1_pymc_jax.py +175 -0
- package/tests/test_gap2_formal.py +86 -0
- package/tests/test_gap3_ledger.py +54 -0
- package/tests/test_gap4_parity.py +202 -0
- package/tests/test_general_model_dimensions.py +36 -0
- package/tests/test_general_model_engine.py +230 -0
- package/tests/test_import_contract.py +24 -0
- package/tests/test_numerical_reference.py +247 -0
- package/tests/test_numerical_verification.py +124 -0
- package/tests/test_pde_solver_selection.py +92 -0
- package/tests/test_portable_standard_export.py +84 -0
- package/tests/test_reasoning_ablation.py +159 -0
- package/tests/test_reasoning_benchmark.py +467 -0
- package/tests/test_reasoning_cli.py +99 -0
- package/tests/test_reasoning_contracts.py +221 -0
- package/tests/test_reasoning_quantum.py +165 -0
- package/tests/test_router_availability_hardening.py +18 -0
- package/tests/test_scientific_input_validation.py +93 -0
- package/tests/test_scientific_upgrade_112.py +208 -0
- package/tests/test_security_hardening.py +171 -0
- package/tests/test_standard_export_service_contract.py +44 -0
- package/tests/test_surrogate_interfaces.py +66 -0
- package/tests/test_surrogate_modeling.py +150 -0
- package/tests/test_tools.py +202 -0
- package/tests/test_validate_runtime_hardening.py +55 -0
- package/tests/test_z3_domain_hardening.py +15 -0
package/.gitattributes
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Store all text as LF in the repo so the same blob checks out identically
|
|
2
|
+
# everywhere; git still hands the working copy the OS-preferred ending via
|
|
3
|
+
# core.autocrlf where configured.
|
|
4
|
+
* text=auto eol=lf
|
|
5
|
+
|
|
6
|
+
# Windows launchers must keep CRLF , cmd.exe mis-parses LF-only batch files
|
|
7
|
+
# in some cases, and these are the documented entry points.
|
|
8
|
+
*.bat text eol=crlf
|
|
9
|
+
*.cmd text eol=crlf
|
|
10
|
+
*.ps1 text eol=crlf
|
|
11
|
+
|
|
12
|
+
# Binary assets , never normalize, never diff as text.
|
|
13
|
+
*.png binary
|
|
14
|
+
*.jpg binary
|
|
15
|
+
*.jpeg binary
|
|
16
|
+
*.gif binary
|
|
17
|
+
*.ico binary
|
|
18
|
+
*.pdf binary
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Something in the skill or tools is wrong
|
|
4
|
+
title: "[BUG] "
|
|
5
|
+
labels: bug
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**What happened?**
|
|
9
|
+
<!-- Include the exact phase/output where the skill misbehaved -->
|
|
10
|
+
|
|
11
|
+
**Reproduction:** which idea/prompt triggered it?
|
|
12
|
+
|
|
13
|
+
**Environment:** runtime (Claude Code / opencode / other), model, OS
|
|
14
|
+
|
|
15
|
+
**Expected behavior per SKILL.md:** <!-- quote the rule that was violated, if any -->
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# What does this PR change?
|
|
2
|
+
<!-- one paragraph -->
|
|
3
|
+
|
|
4
|
+
# Checklist
|
|
5
|
+
|
|
6
|
+
- [ ] New/changed markdown passes `python skills/axiomize/tools/check_skill.py`
|
|
7
|
+
- [ ] Perspective files follow the contract in CONTRIBUTING.md (all four sections)
|
|
8
|
+
- [ ] Examples follow the 8-phase structure and include at least one rejected-lens rationale
|
|
9
|
+
- [ ] Tool changes: sanity checks still exit non-zero on failure; default runtime < 60s
|
|
10
|
+
- [ ] No emojis in content; units stated wherever quantities appear
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Axiomize 1.11.2 hardening branch: release only after all final-commit CI and release-preflight gates pass.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Only github-actions. There is no pip manifest in this repo , the two
|
|
4
|
+
# runtime packages the validators need (numpy, scipy) are installed inline
|
|
5
|
+
# by the CI step, so there is nothing for the pip ecosystem to watch.
|
|
6
|
+
- package-ecosystem: "github-actions"
|
|
7
|
+
directory: "/"
|
|
8
|
+
schedule:
|
|
9
|
+
interval: "weekly"
|
|
10
|
+
labels:
|
|
11
|
+
- "dependencies"
|
|
12
|
+
- "github-actions"
|
|
13
|
+
commit-message:
|
|
14
|
+
prefix: "ci"
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Installed-wheel CLI smoke gate for all advanced Model IR families."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import math
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
import tempfile
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SmokeFailure(RuntimeError):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _assert(condition: bool, message: str) -> None:
|
|
21
|
+
if not condition:
|
|
22
|
+
raise SmokeFailure(message)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _exe() -> str:
|
|
26
|
+
path = shutil.which("axiomize")
|
|
27
|
+
if not path:
|
|
28
|
+
raise SmokeFailure("installed axiomize console entry point not found")
|
|
29
|
+
return path
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _run_model(work: Path, name: str, model_ir: dict[str, Any], **extra: Any) -> dict[str, Any]:
|
|
33
|
+
request = work / f"{name}.json"
|
|
34
|
+
request.write_text(json.dumps({"model_ir": model_ir, **extra}), encoding="utf-8")
|
|
35
|
+
proc = subprocess.run(
|
|
36
|
+
[_exe(), "model", "--action", "simulate", "--input-json", str(request)],
|
|
37
|
+
text=True,
|
|
38
|
+
capture_output=True,
|
|
39
|
+
timeout=90,
|
|
40
|
+
check=False,
|
|
41
|
+
)
|
|
42
|
+
if proc.returncode != 0:
|
|
43
|
+
raise SmokeFailure(f"{name}: CLI exited {proc.returncode}\nstdout={proc.stdout}\nstderr={proc.stderr}")
|
|
44
|
+
try:
|
|
45
|
+
payload = json.loads(proc.stdout)
|
|
46
|
+
except json.JSONDecodeError as exc:
|
|
47
|
+
raise SmokeFailure(f"{name}: CLI stdout is not JSON: {proc.stdout}") from exc
|
|
48
|
+
if not isinstance(payload, dict):
|
|
49
|
+
raise SmokeFailure(f"{name}: CLI returned non-object JSON")
|
|
50
|
+
return payload
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _base(name: str, family: str, variables: list[dict[str, Any]], parameters: list[dict[str, Any]],
|
|
54
|
+
equations: list[dict[str, Any]], metadata: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
55
|
+
return {
|
|
56
|
+
"schema_version": "1.0",
|
|
57
|
+
"name": name,
|
|
58
|
+
"domain": "general",
|
|
59
|
+
"family": family,
|
|
60
|
+
"independent_variable": "t",
|
|
61
|
+
"independent_unit": "dimensionless",
|
|
62
|
+
"variables": variables,
|
|
63
|
+
"parameters": parameters,
|
|
64
|
+
"equations": equations,
|
|
65
|
+
"metadata": metadata or {},
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _test_pde(work: Path) -> None:
|
|
70
|
+
model = _base(
|
|
71
|
+
"smoke-pde", "pde", [{"name": "u", "initial": 1.0}], [{"name": "k", "value": 0.5}],
|
|
72
|
+
[{"target": "u", "expression": "-k*u", "kind": "derivative"}],
|
|
73
|
+
{"pde": {"grid_points": 8, "diffusion": {"u": 0.1}}},
|
|
74
|
+
)
|
|
75
|
+
out = _run_model(work, "pde", model, t_span=[0.0, 0.5], points=12)
|
|
76
|
+
_assert(out.get("status") == "PASS", f"PDE failed: {out}")
|
|
77
|
+
final = sum(out["states"]["u"][-1]) / len(out["states"]["u"][-1])
|
|
78
|
+
_assert(abs(final - math.exp(-0.25)) < 2e-3, f"PDE numeric mismatch: {final}")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _test_dae(work: Path) -> None:
|
|
82
|
+
model = _base(
|
|
83
|
+
"smoke-dae", "dae",
|
|
84
|
+
[{"name": "x", "initial": 1.0}, {"name": "z", "role": "latent", "initial": 1.0}],
|
|
85
|
+
[{"name": "k", "value": 1.0}],
|
|
86
|
+
[
|
|
87
|
+
{"target": "x", "expression": "-z", "kind": "derivative"},
|
|
88
|
+
{"target": "", "expression": "z-k*x", "kind": "residual"},
|
|
89
|
+
],
|
|
90
|
+
)
|
|
91
|
+
out = _run_model(work, "dae", model, t_span=[0.0, 0.5], points=12)
|
|
92
|
+
_assert(out.get("status") == "PASS", f"DAE failed: {out}")
|
|
93
|
+
_assert(out["diagnostics"]["max_algebraic_residual"] < 1e-6, "DAE algebraic residual too large")
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _test_optimization(work: Path) -> None:
|
|
97
|
+
model = _base(
|
|
98
|
+
"smoke-opt", "optimization",
|
|
99
|
+
[{"name": "x", "role": "decision", "initial": 0.0, "bounds": [-10.0, 10.0]}], [],
|
|
100
|
+
[{"target": "", "expression": "(x-2)**2", "kind": "objective"}],
|
|
101
|
+
{"optimization": {"objective": "(x-2)**2"}},
|
|
102
|
+
)
|
|
103
|
+
out = _run_model(work, "optimization", model)
|
|
104
|
+
_assert(out.get("status") == "PASS", f"optimization failed: {out}")
|
|
105
|
+
_assert(abs(float(out["states"]["x"]) - 2.0) < 1e-3, "optimization optimum mismatch")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _test_control(work: Path) -> None:
|
|
109
|
+
model = _base(
|
|
110
|
+
"smoke-control", "control", [{"name": "x", "initial": 1.0}], [],
|
|
111
|
+
[{"target": "x", "expression": "0", "kind": "state_space"}],
|
|
112
|
+
{"control": {"A": [[-1.0]], "B": [[0.0]], "C": [[1.0]], "D": [[0.0]], "input": 0.0}},
|
|
113
|
+
)
|
|
114
|
+
out = _run_model(work, "control", model, t_span=[0.0, 0.5], points=12)
|
|
115
|
+
_assert(out.get("status") == "PASS", f"control failed: {out}")
|
|
116
|
+
_assert(out["diagnostics"]["stability"] == "stable", "control stability mismatch")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _test_network(work: Path) -> None:
|
|
120
|
+
model = _base(
|
|
121
|
+
"smoke-network", "network", [{"name": "x", "initial": 0.5}], [{"name": "c", "value": 0.5}],
|
|
122
|
+
[{"target": "x", "expression": "c*laplacian_x", "kind": "derivative"}],
|
|
123
|
+
{"network": {"nodes": ["a", "b"], "edges": [["a", "b"]], "initial": {"x": [1.0, 0.0]}}},
|
|
124
|
+
)
|
|
125
|
+
out = _run_model(work, "network", model, t_span=[0.0, 0.5], points=12)
|
|
126
|
+
_assert(out.get("status") == "PASS", f"network failed: {out}")
|
|
127
|
+
_assert(len(out["states"]["x"][-1]) == 2, "network node state shape mismatch")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _test_bayesian(work: Path) -> None:
|
|
131
|
+
model = _base(
|
|
132
|
+
"smoke-bayes", "bayesian", [{"name": "y", "role": "output", "initial": 0.0}],
|
|
133
|
+
[{"name": "a", "value": 0.5, "fit": True, "prior": {"dist": "normal", "mu": 0.0, "sigma": 3.0}}],
|
|
134
|
+
[{"target": "y", "expression": "a*x", "kind": "observation"}],
|
|
135
|
+
{"bayesian": {
|
|
136
|
+
"data": {"x": [0.0, 1.0, 2.0, 3.0]},
|
|
137
|
+
"observations": [0.0, 2.0, 4.0, 6.0],
|
|
138
|
+
"mean_expression": "a*x", "sigma": 0.2,
|
|
139
|
+
"draws": 200, "burn": 60, "proposal_scale": {"a": 0.1},
|
|
140
|
+
}},
|
|
141
|
+
)
|
|
142
|
+
blocked = _run_model(work, "bayesian-blocked", model, seed=17)
|
|
143
|
+
_assert(blocked.get("status") == "APPROVAL_REQUIRED", "Bayesian compute must require explicit approval")
|
|
144
|
+
out = _run_model(work, "bayesian", model, seed=17, approve_heavy=True)
|
|
145
|
+
_assert(out.get("status") == "PASS", f"Bayesian failed: {out}")
|
|
146
|
+
_assert(abs(float(out["posterior"]["a"]["mean"]) - 2.0) < 0.35, "Bayesian posterior mismatch")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _test_agent_based(work: Path) -> None:
|
|
150
|
+
model = _base(
|
|
151
|
+
"smoke-abm", "agent_based", [{"name": "x", "initial": 1.0}], [{"name": "k", "value": 0.5}],
|
|
152
|
+
[{"target": "x", "expression": "-k*x", "kind": "derivative"}],
|
|
153
|
+
{"agents": {"count": 3}},
|
|
154
|
+
)
|
|
155
|
+
out = _run_model(work, "agent-based", model, t_span=[0.0, 0.5], points=12, seed=3)
|
|
156
|
+
_assert(out.get("status") == "PASS", f"agent-based failed: {out}")
|
|
157
|
+
_assert(len(out["states"]["x"][-1]) == 3, "agent state shape mismatch")
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _test_discrete_event(work: Path) -> None:
|
|
161
|
+
model = _base(
|
|
162
|
+
"smoke-des", "discrete_event", [{"name": "n", "initial": 0.0}], [{"name": "lam", "value": 10.0}],
|
|
163
|
+
[{"target": "n", "expression": "0", "kind": "event_state"}],
|
|
164
|
+
{"discrete_event": {"events": [{"name": "arrival", "rate": "lam", "delta": {"n": 1.0}}]}},
|
|
165
|
+
)
|
|
166
|
+
out = _run_model(work, "discrete-event", model, t_span=[0.0, 1.0], points=12, seed=9)
|
|
167
|
+
_assert(out.get("status") == "PASS", f"discrete-event failed: {out}")
|
|
168
|
+
_assert(out["diagnostics"]["total_events"] > 0, "discrete-event produced no events")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _test_hybrid(work: Path) -> None:
|
|
172
|
+
model = _base(
|
|
173
|
+
"smoke-hybrid", "hybrid", [{"name": "x", "initial": 1.0}], [],
|
|
174
|
+
[{"target": "x", "expression": "-1", "kind": "derivative"}],
|
|
175
|
+
{"hybrid": {"events": [{"name": "reset", "expression": "x", "direction": -1, "reset": {"x": "1"}}]}},
|
|
176
|
+
)
|
|
177
|
+
out = _run_model(work, "hybrid", model, t_span=[0.0, 1.3], points=18)
|
|
178
|
+
_assert(out.get("status") == "PASS", f"hybrid failed: {out}")
|
|
179
|
+
_assert(out["diagnostics"]["event_count"] >= 1, "hybrid event did not fire")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _test_causal(work: Path) -> None:
|
|
183
|
+
model = _base(
|
|
184
|
+
"smoke-causal", "causal", [{"name": "y", "role": "output", "initial": 0.0}], [],
|
|
185
|
+
[{"target": "y", "expression": "0", "kind": "causal"}],
|
|
186
|
+
{
|
|
187
|
+
"causal_identification": {"randomized": True},
|
|
188
|
+
"causal": {
|
|
189
|
+
"treatment": "treat", "outcome": "outcome", "identification": {"randomized": True},
|
|
190
|
+
"data": {"treat": [0.0, 1.0, 0.0, 1.0], "outcome": [1.0, 3.0, 1.0, 3.0]},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
)
|
|
194
|
+
out = _run_model(work, "causal", model)
|
|
195
|
+
_assert(out.get("status") == "PASS", f"causal failed: {out}")
|
|
196
|
+
_assert(abs(float(out["causal_effect"]["estimate"]) - 2.0) < 1e-9, "causal effect mismatch")
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _test_multiphysics(work: Path) -> None:
|
|
200
|
+
source = _base(
|
|
201
|
+
"source", "ode", [{"name": "x", "initial": 2.0}], [],
|
|
202
|
+
[{"target": "x", "expression": "0", "kind": "derivative"}],
|
|
203
|
+
)
|
|
204
|
+
target = _base(
|
|
205
|
+
"target", "ode", [{"name": "y", "initial": 1.0}], [{"name": "k", "value": 1.0}],
|
|
206
|
+
[{"target": "y", "expression": "-k*y", "kind": "derivative"}],
|
|
207
|
+
)
|
|
208
|
+
model = _base(
|
|
209
|
+
"smoke-multiphysics", "multiphysics", [{"name": "q", "initial": 0.0}], [],
|
|
210
|
+
[{"target": "q", "expression": "0", "kind": "coupling"}],
|
|
211
|
+
{"multiphysics": {
|
|
212
|
+
"components": {"source": source, "target": target},
|
|
213
|
+
"couplings": [{
|
|
214
|
+
"from_component": "source", "from_state": "x",
|
|
215
|
+
"to_component": "target", "to_parameter": "k",
|
|
216
|
+
"reduction": "final", "scale": 0.5,
|
|
217
|
+
}],
|
|
218
|
+
"max_iterations": 4, "tolerance": 1e-10,
|
|
219
|
+
}},
|
|
220
|
+
)
|
|
221
|
+
blocked = _run_model(work, "multiphysics-blocked", model, t_span=[0.0, 0.5], points=10)
|
|
222
|
+
_assert(blocked.get("status") == "APPROVAL_REQUIRED", "multiphysics must require approval")
|
|
223
|
+
out = _run_model(work, "multiphysics", model, t_span=[0.0, 0.5], points=10, approve_heavy=True)
|
|
224
|
+
_assert(out.get("status") == "PASS", f"multiphysics failed: {out}")
|
|
225
|
+
_assert(out["diagnostics"]["converged"] is True, "multiphysics coupling did not converge")
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def main() -> int:
|
|
229
|
+
with tempfile.TemporaryDirectory(prefix="axiomize-advanced-family-smoke-") as tmp:
|
|
230
|
+
work = Path(tmp)
|
|
231
|
+
tests = [
|
|
232
|
+
_test_pde, _test_dae, _test_optimization, _test_control, _test_network,
|
|
233
|
+
_test_bayesian, _test_agent_based, _test_discrete_event, _test_hybrid,
|
|
234
|
+
_test_causal, _test_multiphysics,
|
|
235
|
+
]
|
|
236
|
+
for test in tests:
|
|
237
|
+
test(work)
|
|
238
|
+
print(f"PASS {test.__name__.removeprefix('_test_')}")
|
|
239
|
+
print("RESULT: PASS - installed CLI executes every advanced Model IR family")
|
|
240
|
+
return 0
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
if __name__ == "__main__":
|
|
244
|
+
try:
|
|
245
|
+
raise SystemExit(main())
|
|
246
|
+
except SmokeFailure as exc:
|
|
247
|
+
print(f"RESULT: FAIL - {exc}", file=sys.stderr)
|
|
248
|
+
raise SystemExit(1)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Fail CI when package/release metadata drift or release provenance is unsafe."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
ROOT = Path(__file__).resolve().parents[2]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _project_version() -> str:
|
|
16
|
+
text = (ROOT / "pyproject.toml").read_text(encoding="utf-8")
|
|
17
|
+
try:
|
|
18
|
+
project = text.split("[project]", 1)[1].split("\n[", 1)[0]
|
|
19
|
+
except IndexError as exc:
|
|
20
|
+
raise RuntimeError("pyproject.toml has no [project] section") from exc
|
|
21
|
+
match = re.search(r'^version\s*=\s*"([^"]+)"\s*$', project, re.MULTILINE)
|
|
22
|
+
if not match:
|
|
23
|
+
raise RuntimeError("[project] has no literal version")
|
|
24
|
+
return match.group(1)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _runtime_version() -> str:
|
|
28
|
+
text = (ROOT / "src" / "axiomize" / "__init__.py").read_text(encoding="utf-8")
|
|
29
|
+
match = re.search(r'^__version__\s*=\s*"([^"]+)"\s*$', text, re.MULTILINE)
|
|
30
|
+
if not match:
|
|
31
|
+
raise RuntimeError("src/axiomize/__init__.py has no __version__")
|
|
32
|
+
return match.group(1)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _trigger_version() -> str:
|
|
36
|
+
lines = (ROOT / ".github" / "pypi-release-trigger").read_text(encoding="utf-8").splitlines()
|
|
37
|
+
if not lines:
|
|
38
|
+
raise RuntimeError(".github/pypi-release-trigger is empty")
|
|
39
|
+
match = re.fullmatch(r"axiomize-quantum-skills-2\.0\s+([^\s]+)", lines[0].strip())
|
|
40
|
+
if not match:
|
|
41
|
+
raise RuntimeError("first trigger line must be: axiomize-quantum-skills-2.0 <version>")
|
|
42
|
+
return match.group(1)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _readme_version() -> str:
|
|
46
|
+
text = (ROOT / "README.md").read_text(encoding="utf-8")
|
|
47
|
+
match = re.search(r"^Current package line:\s*\*\*([^*]+)\*\*", text, re.MULTILINE)
|
|
48
|
+
if not match:
|
|
49
|
+
raise RuntimeError("README.md has no 'Current package line' version")
|
|
50
|
+
return match.group(1).strip()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _changelog_version() -> str:
|
|
54
|
+
text = (ROOT / "CHANGELOG.md").read_text(encoding="utf-8")
|
|
55
|
+
match = re.search(r"^## \[([^\]]+)\]", text, re.MULTILINE)
|
|
56
|
+
if not match:
|
|
57
|
+
raise RuntimeError("CHANGELOG.md has no release heading")
|
|
58
|
+
return match.group(1).strip()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _release_ref_is_allowed() -> bool:
|
|
62
|
+
"""Block release-workflow execution from feature branches.
|
|
63
|
+
|
|
64
|
+
``workflow_dispatch`` is useful for retrying a failed release, but without
|
|
65
|
+
this guard GitHub allows a user to dispatch the workflow against an
|
|
66
|
+
arbitrary branch. The release workflow must only ever publish content from
|
|
67
|
+
the repository's main branch.
|
|
68
|
+
"""
|
|
69
|
+
if os.environ.get("GITHUB_ACTIONS") != "true":
|
|
70
|
+
return True
|
|
71
|
+
if os.environ.get("GITHUB_WORKFLOW") != "Release":
|
|
72
|
+
return True
|
|
73
|
+
ref = os.environ.get("GITHUB_REF", "")
|
|
74
|
+
if ref != "refs/heads/main":
|
|
75
|
+
print(
|
|
76
|
+
f"FAIL: Release workflow may run only from refs/heads/main; got {ref or '<missing>'}",
|
|
77
|
+
file=sys.stderr,
|
|
78
|
+
)
|
|
79
|
+
return False
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def main() -> int:
|
|
84
|
+
versions = {
|
|
85
|
+
"pyproject": _project_version(),
|
|
86
|
+
"runtime": _runtime_version(),
|
|
87
|
+
"pypi_trigger": _trigger_version(),
|
|
88
|
+
"readme": _readme_version(),
|
|
89
|
+
"changelog": _changelog_version(),
|
|
90
|
+
}
|
|
91
|
+
for name, value in versions.items():
|
|
92
|
+
print(f"{name:12s} {value}")
|
|
93
|
+
if len(set(versions.values())) != 1:
|
|
94
|
+
print("FAIL: release versions differ; update package, trigger and public docs together", file=sys.stderr)
|
|
95
|
+
return 1
|
|
96
|
+
if not _release_ref_is_allowed():
|
|
97
|
+
return 1
|
|
98
|
+
print("PASS: release version contract is synchronized and release ref is authorized")
|
|
99
|
+
return 0
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
raise SystemExit(main())
|