xtalate 0.1.0.dev0__tar.gz → 0.3.0__tar.gz
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.
- xtalate-0.3.0/.github/ISSUE_TEMPLATE/bug_incorrect_conversion.yml +50 -0
- xtalate-0.3.0/.github/ISSUE_TEMPLATE/bug_parse_failure.yml +54 -0
- xtalate-0.3.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- xtalate-0.3.0/.github/ISSUE_TEMPLATE/format_request.yml +48 -0
- xtalate-0.3.0/.github/ISSUE_TEMPLATE/general.yml +16 -0
- xtalate-0.3.0/.github/PULL_REQUEST_TEMPLATE.md +32 -0
- xtalate-0.3.0/.github/workflows/ci.yml +61 -0
- xtalate-0.3.0/.github/workflows/nightly.yml +106 -0
- xtalate-0.3.0/CHANGELOG.md +501 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/CITATION.cff +2 -2
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/CLAUDE.md +29 -14
- xtalate-0.3.0/CONTRIBUTING.md +178 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/PKG-INFO +27 -11
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/README.md +21 -10
- xtalate-0.3.0/benchmarks/__init__.py +12 -0
- xtalate-0.3.0/benchmarks/__main__.py +7 -0
- xtalate-0.3.0/benchmarks/harness.py +416 -0
- xtalate-0.3.0/docs/DECISIONS.md +519 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/IMPLEMENTATION_PLAN_v0.3.md +1 -1
- xtalate-0.3.0/docs/M14-M16_SLICE_PLAN.md +327 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/MASTER_SPEC.md +24 -10
- xtalate-0.3.0/docs/MEMORY_CEILING.md +135 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/pyproject.toml +45 -1
- xtalate-0.3.0/src/xtalate/__init__.py +14 -0
- xtalate-0.3.0/src/xtalate/_time.py +21 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/capabilities/registry.py +17 -5
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/cli/main.py +274 -33
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/conversion/__init__.py +3 -0
- xtalate-0.3.0/src/xtalate/conversion/engine.py +1390 -0
- xtalate-0.3.0/src/xtalate/conversion/parse_recovery.py +203 -0
- xtalate-0.3.0/src/xtalate/conversion/preflight.py +352 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/exporters/__init__.py +16 -2
- xtalate-0.3.0/src/xtalate/exporters/_common.py +33 -0
- xtalate-0.3.0/src/xtalate/exporters/ase_traj.py +210 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/exporters/extxyz.py +55 -11
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/exporters/poscar.py +50 -20
- xtalate-0.3.0/src/xtalate/exporters/xdatcar.py +212 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/exporters/xyz.py +10 -1
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/parsers/__init__.py +16 -2
- xtalate-0.3.0/src/xtalate/parsers/_common.py +92 -0
- xtalate-0.3.0/src/xtalate/parsers/ase_traj.py +527 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/parsers/extxyz.py +276 -8
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/parsers/poscar.py +240 -22
- xtalate-0.3.0/src/xtalate/parsers/xdatcar.py +682 -0
- xtalate-0.3.0/src/xtalate/parsers/xyz.py +357 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/recovery/__init__.py +14 -2
- xtalate-0.3.0/src/xtalate/recovery/engine.py +977 -0
- xtalate-0.3.0/src/xtalate/recovery/scenarios.py +172 -0
- xtalate-0.3.0/src/xtalate/registry.py +128 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/schema/__init__.py +2 -1
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/schema/models.py +24 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/schema/paths.py +8 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/schema/presence.py +132 -3
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/sdk/__init__.py +16 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/sdk/capabilities.py +21 -0
- xtalate-0.3.0/src/xtalate/sdk/plugins.py +143 -0
- xtalate-0.3.0/src/xtalate/sdk/streaming.py +240 -0
- xtalate-0.3.0/src/xtalate/validation/_shared.py +34 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/validation/engine.py +28 -25
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/validation/rethreshold.py +5 -18
- xtalate-0.3.0/src/xtalate/validation/streaming.py +617 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/validation/tolerance.py +77 -3
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/_dummy_plugins.py +8 -2
- xtalate-0.3.0/tests/_fake_entry_points.py +50 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/capabilities/test_registry.py +13 -0
- xtalate-0.3.0/tests/capabilities/test_velocity_mass_rows.py +49 -0
- xtalate-0.3.0/tests/cli/_worked_example.py +64 -0
- xtalate-0.3.0/tests/cli/test_cli.py +537 -0
- xtalate-0.3.0/tests/cli/test_plugin_failures.py +80 -0
- xtalate-0.3.0/tests/cli/test_streaming_convert.py +170 -0
- xtalate-0.3.0/tests/cli/test_worked_example.py +103 -0
- xtalate-0.3.0/tests/cli/worked_example/conversion.expected.json +87 -0
- xtalate-0.3.0/tests/cli/worked_example/validation.expected.json +176 -0
- xtalate-0.3.0/tests/conftest.py +57 -0
- xtalate-0.3.0/tests/conversion/test_engine.py +416 -0
- xtalate-0.3.0/tests/conversion/test_frame_reduction_completeness.py +226 -0
- xtalate-0.3.0/tests/conversion/test_parse_recovery.py +195 -0
- xtalate-0.3.0/tests/conversion/test_partial_lattice_fabrication.py +145 -0
- xtalate-0.3.0/tests/conversion/test_preflight.py +215 -0
- xtalate-0.3.0/tests/conversion/test_velocity_recovery.py +237 -0
- xtalate-0.3.0/tests/conversion/test_xdatcar_truncate_recovery.py +170 -0
- xtalate-0.3.0/tests/exporters/test_poscar.py +111 -0
- xtalate-0.3.0/tests/exporters/test_xdatcar.py +235 -0
- xtalate-0.3.0/tests/fixtures/xtalate_toyfmt/pyproject.toml +37 -0
- xtalate-0.3.0/tests/fixtures/xtalate_toyfmt/src/xtalate_toyfmt/__init__.py +15 -0
- xtalate-0.3.0/tests/fixtures/xtalate_toyfmt/src/xtalate_toyfmt/exporter.py +50 -0
- xtalate-0.3.0/tests/fixtures/xtalate_toyfmt/src/xtalate_toyfmt/parser.py +135 -0
- xtalate-0.3.0/tests/golden/ATTRIBUTIONS.md +76 -0
- xtalate-0.3.0/tests/golden/_governance.py +371 -0
- xtalate-0.3.0/tests/golden/ase_traj/_generate.py +110 -0
- xtalate-0.3.0/tests/golden/ase_traj/co-relax-3frame/expected.canonical.json +335 -0
- xtalate-0.3.0/tests/golden/ase_traj/co-relax-3frame/manifest.yaml +24 -0
- xtalate-0.3.0/tests/golden/ase_traj/co-relax-3frame/relax.traj +0 -0
- xtalate-0.3.0/tests/golden/ase_traj/water-single-molecule/expected.canonical.json +83 -0
- xtalate-0.3.0/tests/golden/ase_traj/water-single-molecule/manifest.yaml +20 -0
- xtalate-0.3.0/tests/golden/ase_traj/water-single-molecule/relax.traj +0 -0
- xtalate-0.3.0/tests/golden/contcar/co-md-restart/CONTCAR +14 -0
- xtalate-0.3.0/tests/golden/contcar/co-md-restart/expected.canonical.json +118 -0
- xtalate-0.3.0/tests/golden/contcar/co-md-restart/manifest.yaml +19 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/extxyz/co-in-cell/manifest.yaml +1 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/poscar/nacl-primitive/expected.canonical.json +3 -13
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/poscar/nacl-primitive/manifest.yaml +3 -2
- xtalate-0.3.0/tests/golden/test_ase_traj_golden.py +98 -0
- xtalate-0.3.0/tests/golden/test_corpus_governance.py +107 -0
- xtalate-0.3.0/tests/golden/test_xdatcar_golden.py +92 -0
- xtalate-0.3.0/tests/golden/xdatcar/nacl-md-fixed-cell/XDATCAR +22 -0
- xtalate-0.3.0/tests/golden/xdatcar/nacl-md-fixed-cell/expected.canonical.json +277 -0
- xtalate-0.3.0/tests/golden/xdatcar/nacl-md-fixed-cell/manifest.yaml +22 -0
- xtalate-0.3.0/tests/golden/xdatcar/si-npt-variable-cell/XDATCAR +30 -0
- xtalate-0.3.0/tests/golden/xdatcar/si-npt-variable-cell/expected.canonical.json +235 -0
- xtalate-0.3.0/tests/golden/xdatcar/si-npt-variable-cell/manifest.yaml +20 -0
- xtalate-0.3.0/tests/golden/xdatcar/si-single-configuration/XDATCAR +10 -0
- xtalate-0.3.0/tests/golden/xdatcar/si-single-configuration/expected.canonical.json +105 -0
- xtalate-0.3.0/tests/golden/xdatcar/si-single-configuration/manifest.yaml +17 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/xyz/water-traj/manifest.yaml +1 -0
- xtalate-0.3.0/tests/parsers/test_ase_traj.py +206 -0
- xtalate-0.3.0/tests/parsers/test_ase_traj_smoke.py +116 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/parsers/test_builtins_registration.py +32 -2
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/parsers/test_extxyz.py +28 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/parsers/test_poscar.py +106 -2
- xtalate-0.3.0/tests/parsers/test_xdatcar.py +426 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/parsers/test_xyz.py +7 -0
- xtalate-0.3.0/tests/property/_generators.py +215 -0
- xtalate-0.3.0/tests/property/_properties.py +114 -0
- xtalate-0.3.0/tests/property/_strategies.py +188 -0
- xtalate-0.3.0/tests/property/test_fabricative_recovery_completeness.py +159 -0
- xtalate-0.3.0/tests/property/test_report_completeness.py +161 -0
- xtalate-0.3.0/tests/property/test_report_completeness_hypothesis.py +76 -0
- xtalate-0.3.0/tests/recovery/test_engine.py +437 -0
- xtalate-0.3.0/tests/recovery/test_missing_masses.py +117 -0
- xtalate-0.3.0/tests/recovery/test_missing_velocities.py +209 -0
- xtalate-0.3.0/tests/recovery/test_physics_maxwell_boltzmann.py +56 -0
- xtalate-0.3.0/tests/recovery/test_scenarios.py +128 -0
- xtalate-0.3.0/tests/roundtrip/_compare.py +85 -0
- xtalate-0.3.0/tests/roundtrip/_matrix.py +204 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/roundtrip/test_identity.py +7 -0
- xtalate-0.3.0/tests/roundtrip/test_matrix_enumeration.py +102 -0
- xtalate-0.3.0/tests/roundtrip/test_three_hop.py +86 -0
- xtalate-0.3.0/tests/roundtrip/test_two_hop.py +104 -0
- xtalate-0.3.0/tests/schema/__init__.py +0 -0
- {xtalate-0.1.0.dev0/tests/golden/schema → xtalate-0.3.0/tests/schema/fixtures}/poscar_nacl.json +3 -13
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/schema/test_golden_roundtrip.py +5 -3
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/schema/test_models.py +30 -0
- xtalate-0.3.0/tests/sdk/__init__.py +0 -0
- xtalate-0.3.0/tests/streaming/__init__.py +0 -0
- xtalate-0.3.0/tests/streaming/_generators.py +147 -0
- xtalate-0.3.0/tests/streaming/test_streaming_conversion.py +180 -0
- xtalate-0.3.0/tests/streaming/test_streaming_frame_selection.py +189 -0
- xtalate-0.3.0/tests/streaming/test_streaming_memory.py +146 -0
- xtalate-0.3.0/tests/streaming/test_streaming_parse_export.py +107 -0
- xtalate-0.3.0/tests/streaming/test_streaming_presence.py +94 -0
- xtalate-0.3.0/tests/streaming/test_streaming_sdk.py +133 -0
- xtalate-0.3.0/tests/streaming/test_streaming_validation.py +150 -0
- xtalate-0.3.0/tests/test_entry_point_discovery.py +195 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/test_smoke.py +1 -1
- xtalate-0.3.0/tests/test_toyfmt_plugin.py +114 -0
- xtalate-0.3.0/tests/validation/__init__.py +0 -0
- xtalate-0.3.0/tests/validation/test_tolerance.py +105 -0
- xtalate-0.1.0.dev0/.claude/settings.local.json +0 -39
- xtalate-0.1.0.dev0/.github/workflows/ci.yml +0 -48
- xtalate-0.1.0.dev0/.import_linter_cache/.gitignore +0 -2
- xtalate-0.1.0.dev0/.import_linter_cache/711309a5eafe379c50451bc7ebdb0a6d9c6d28e6.data.json +0 -1
- xtalate-0.1.0.dev0/.import_linter_cache/CACHEDIR.TAG +0 -3
- xtalate-0.1.0.dev0/.import_linter_cache/xtalate.meta.json +0 -1
- xtalate-0.1.0.dev0/CHANGELOG.md +0 -47
- xtalate-0.1.0.dev0/docs/DECISIONS.md +0 -292
- xtalate-0.1.0.dev0/src/xtalate/__init__.py +0 -10
- xtalate-0.1.0.dev0/src/xtalate/conversion/engine.py +0 -560
- xtalate-0.1.0.dev0/src/xtalate/conversion/preflight.py +0 -127
- xtalate-0.1.0.dev0/src/xtalate/parsers/_common.py +0 -57
- xtalate-0.1.0.dev0/src/xtalate/parsers/xyz.py +0 -286
- xtalate-0.1.0.dev0/src/xtalate/recovery/engine.py +0 -321
- xtalate-0.1.0.dev0/src/xtalate/recovery/scenarios.py +0 -86
- xtalate-0.1.0.dev0/src/xtalate/registry.py +0 -28
- xtalate-0.1.0.dev0/src/xtalate/sdk/plugins.py +0 -72
- xtalate-0.1.0.dev0/tests/cli/test_cli.py +0 -220
- xtalate-0.1.0.dev0/tests/conversion/test_engine.py +0 -193
- xtalate-0.1.0.dev0/tests/conversion/test_preflight.py +0 -111
- xtalate-0.1.0.dev0/tests/recovery/test_engine.py +0 -175
- xtalate-0.1.0.dev0/tests/recovery/test_scenarios.py +0 -35
- xtalate-0.1.0.dev0/tests/validation/test_tolerance.py +0 -56
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/.gitignore +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/LICENSE +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/NOTICE +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/ARCHITECTURE_REVIEW.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/IMPLEMENTATION_PLAN_v0.1.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/IMPLEMENTATION_PLAN_v0.2.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/IMPLEMENTATION_PLAN_v0.4.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/IMPLEMENTATION_PLAN_v0.5.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/IMPLEMENTATION_PLAN_v0.6.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/IMPLEMENTATION_PLAN_v0.7.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/IMPLEMENTATION_PLAN_v1.0.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/docs/Incremental_Roadmap_v1.0.md +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/examples/.gitkeep +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/examples/convert_extxyz_to_poscar.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/capabilities/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/cli/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/cli/render.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/conversion/report.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/discovery/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/discovery/engine.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/discovery/report.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/discovery/sniffer.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/py.typed +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/schema/arrays.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/schema/elements.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/sdk/results.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/validation/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/src/xtalate/validation/report.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/_format_helpers.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/capabilities/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/cli/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/conversion/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/discovery/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/discovery/test_engine.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/discovery/test_sniffer.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/exporters/__init__.py +0 -0
- /xtalate-0.1.0.dev0/tests/golden/.gitkeep → /xtalate-0.3.0/tests/fixtures/xtalate_toyfmt/src/xtalate_toyfmt/py.typed +0 -0
- {xtalate-0.1.0.dev0/tests/roundtrip → xtalate-0.3.0/tests/golden}/.gitkeep +0 -0
- {xtalate-0.1.0.dev0/tests/recovery → xtalate-0.3.0/tests/golden}/__init__.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/extxyz/co-in-cell/expected.canonical.json +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/extxyz/co-in-cell/sample.extxyz +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/poscar/nacl-primitive/POSCAR +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/xyz/water-traj/expected.canonical.json +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/golden/xyz/water-traj/water_traj.xyz +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/parsers/__init__.py +0 -0
- {xtalate-0.1.0.dev0/tests/schema → xtalate-0.3.0/tests/property}/__init__.py +0 -0
- {xtalate-0.1.0.dev0/tests/sdk → xtalate-0.3.0/tests/recovery}/__init__.py +0 -0
- /xtalate-0.1.0.dev0/tests/validation/__init__.py → /xtalate-0.3.0/tests/roundtrip/.gitkeep +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/roundtrip/__init__.py +0 -0
- {xtalate-0.1.0.dev0/tests/golden/schema → xtalate-0.3.0/tests/schema/fixtures}/xyz_2frame_3atom.json +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/schema/test_arrays.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/schema/test_paths.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/schema/test_presence.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/sdk/test_contracts.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/validation/test_engine.py +0 -0
- {xtalate-0.1.0.dev0 → xtalate-0.3.0}/tests/validation/test_rethreshold.py +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: "Bug: incorrect conversion"
|
|
2
|
+
description: A conversion kept, dropped, transformed, or fabricated something wrong.
|
|
3
|
+
labels: ["bug", "conversion"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: >-
|
|
8
|
+
The Conversion Report and Validation Report are **designed to be the bug report**
|
|
9
|
+
(`docs/MASTER_SPEC.md` Part 4 §2, Part 5 §3). Paste them below — they tell us far more
|
|
10
|
+
than a prose description can.
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: source
|
|
13
|
+
attributes:
|
|
14
|
+
label: Source file (or minimal reproducer)
|
|
15
|
+
description: >-
|
|
16
|
+
Paste the smallest file that reproduces the problem, or attach it. If it can be
|
|
17
|
+
donated to the golden corpus, say so and its license (see the license field below).
|
|
18
|
+
render: text
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
- type: input
|
|
22
|
+
id: target
|
|
23
|
+
attributes:
|
|
24
|
+
label: Target format
|
|
25
|
+
placeholder: "e.g. poscar"
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
- type: textarea
|
|
29
|
+
id: reports
|
|
30
|
+
attributes:
|
|
31
|
+
label: Conversion Report + Validation Report (JSON)
|
|
32
|
+
description: "Output of `xtalate convert ... --json` (and `xtalate validate ... --json` if relevant)."
|
|
33
|
+
render: json
|
|
34
|
+
validations:
|
|
35
|
+
required: true
|
|
36
|
+
- type: textarea
|
|
37
|
+
id: expected_vs_observed
|
|
38
|
+
attributes:
|
|
39
|
+
label: Expected vs observed
|
|
40
|
+
description: What should the report/output have said or done, and what did it actually do?
|
|
41
|
+
validations:
|
|
42
|
+
required: true
|
|
43
|
+
- type: input
|
|
44
|
+
id: versions
|
|
45
|
+
attributes:
|
|
46
|
+
label: Xtalate + schema versions
|
|
47
|
+
description: "`xtalate --version`, and the `schema_version` from the report."
|
|
48
|
+
placeholder: "xtalate 0.2.0, schema 0.1.0"
|
|
49
|
+
validations:
|
|
50
|
+
required: true
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: "Bug: parse failure"
|
|
2
|
+
description: A file failed to parse, or parsed with a wrong or missing ParseIssue.
|
|
3
|
+
labels: ["bug", "parser"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: file
|
|
7
|
+
attributes:
|
|
8
|
+
label: File (or minimal reproducer)
|
|
9
|
+
description: Paste or attach the file that fails to parse.
|
|
10
|
+
render: text
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: error
|
|
15
|
+
attributes:
|
|
16
|
+
label: Full error envelope / ParseIssue list
|
|
17
|
+
description: >-
|
|
18
|
+
The complete error output (`docs/MASTER_SPEC.md` Part 3 §5, Part 6 §6) — codes,
|
|
19
|
+
messages, line numbers. Run with `--json` if using the CLI.
|
|
20
|
+
render: text
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
- type: input
|
|
24
|
+
id: producer
|
|
25
|
+
attributes:
|
|
26
|
+
label: What produced the file?
|
|
27
|
+
placeholder: "e.g. VASP 6.4, ASE 3.23, hand-written"
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
- type: dropdown
|
|
31
|
+
id: donate
|
|
32
|
+
attributes:
|
|
33
|
+
label: Can this file be donated to the golden corpus?
|
|
34
|
+
description: >-
|
|
35
|
+
If yes, we may add it as a regression fixture. This requires an explicit data
|
|
36
|
+
license (see below) — a file without one cannot be admitted.
|
|
37
|
+
options:
|
|
38
|
+
- "No"
|
|
39
|
+
- "Yes — I hold the rights and grant Apache-2.0 / a compatible license"
|
|
40
|
+
- "Yes — it is published open data (I'll give the license + attribution)"
|
|
41
|
+
validations:
|
|
42
|
+
required: true
|
|
43
|
+
- type: input
|
|
44
|
+
id: license
|
|
45
|
+
attributes:
|
|
46
|
+
label: License status of the file (if donating)
|
|
47
|
+
placeholder: "e.g. CC-BY-4.0 (Materials Project), CC0, my own work"
|
|
48
|
+
- type: input
|
|
49
|
+
id: versions
|
|
50
|
+
attributes:
|
|
51
|
+
label: Xtalate + schema versions
|
|
52
|
+
placeholder: "xtalate 0.2.0, schema 0.1.0"
|
|
53
|
+
validations:
|
|
54
|
+
required: true
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: "Format request"
|
|
2
|
+
description: Request support for a new file format.
|
|
3
|
+
labels: ["enhancement", "format-request"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: >-
|
|
8
|
+
A well-scoped format request — especially with example files and a draft capability
|
|
9
|
+
row — is a genuinely valuable contribution even if you never write a line of code.
|
|
10
|
+
- type: input
|
|
11
|
+
id: name
|
|
12
|
+
attributes:
|
|
13
|
+
label: Format name / spec link
|
|
14
|
+
placeholder: "e.g. CIF — https://www.iucr.org/resources/cif/spec"
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: capability_draft
|
|
19
|
+
attributes:
|
|
20
|
+
label: Which canonical fields can it express? (a draft capability row!)
|
|
21
|
+
description: >-
|
|
22
|
+
Which of the canonical categories (Geometry, Cell, Trajectory, Dynamics, Electronic,
|
|
23
|
+
Metadata) can this format hold, and which can it not? Honest PARTIAL beats optimistic
|
|
24
|
+
FULL — this becomes the format's Capability Matrix row (`docs/MASTER_SPEC.md` Part 3 §3).
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: examples
|
|
29
|
+
attributes:
|
|
30
|
+
label: Example files + license status
|
|
31
|
+
description: >-
|
|
32
|
+
Links or attachments, each with its data license. Licensed examples can seed the
|
|
33
|
+
golden corpus; unlicensed ones cannot be admitted.
|
|
34
|
+
validations:
|
|
35
|
+
required: true
|
|
36
|
+
- type: dropdown
|
|
37
|
+
id: contribute
|
|
38
|
+
attributes:
|
|
39
|
+
label: Would you be willing to contribute a plugin?
|
|
40
|
+
description: >-
|
|
41
|
+
Heads up: the plugin SDK is not frozen until v1.0 (risk R12), so a plugin may need to
|
|
42
|
+
follow SDK changes between minor versions until then.
|
|
43
|
+
options:
|
|
44
|
+
- "No — requesting only"
|
|
45
|
+
- "Maybe, with guidance"
|
|
46
|
+
- "Yes"
|
|
47
|
+
validations:
|
|
48
|
+
required: true
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: "General bug / docs issue"
|
|
2
|
+
description: Anything that doesn't fit the other templates.
|
|
3
|
+
labels: ["triage"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: description
|
|
7
|
+
attributes:
|
|
8
|
+
label: Description
|
|
9
|
+
description: What's the issue? For a docs issue, link the doc/section.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: input
|
|
13
|
+
id: versions
|
|
14
|
+
attributes:
|
|
15
|
+
label: Xtalate + schema versions (if applicable)
|
|
16
|
+
placeholder: "xtalate 0.2.0, schema 0.1.0"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!-- Thanks for contributing to Xtalate. Keep PRs small and single-purpose. -->
|
|
2
|
+
|
|
3
|
+
## What & why
|
|
4
|
+
|
|
5
|
+
<!-- What does this change do, and why? For any nontrivial design decision, name at least
|
|
6
|
+
one reasonable rejected alternative — the standard the whole doc set holds itself to. -->
|
|
7
|
+
|
|
8
|
+
## Rejected alternative (for design changes)
|
|
9
|
+
|
|
10
|
+
<!-- e.g. "Considered threading choices into build_preflight; rejected because it breaks the
|
|
11
|
+
draft's purity (D46)." Delete this section only for pure docs/typo PRs. -->
|
|
12
|
+
|
|
13
|
+
## Checklist
|
|
14
|
+
|
|
15
|
+
- [ ] **Docs updated or confirmed unaffected.** The docs are the constitution; a behavior
|
|
16
|
+
change and its doc change are one PR (`docs/MASTER_SPEC.md` Part 10 §4.6).
|
|
17
|
+
- [ ] **Golden cases added** for new behavior, each with a licensed `manifest.yaml`
|
|
18
|
+
(`08 §3.2`), and `tests/golden/ATTRIBUTIONS.md` regenerated (`python
|
|
19
|
+
tests/golden/_governance.py`) if any manifest changed.
|
|
20
|
+
- [ ] **No parser defaulting introduced** — the absence convention holds and the
|
|
21
|
+
default-laundering suite passes (P3, Part 3 §2).
|
|
22
|
+
- [ ] **Completeness invariant green** — the runtime assertion and the property suite
|
|
23
|
+
(`tests/property/`) both pass; no field is lost, dropped, or fabricated silently (P1/P4).
|
|
24
|
+
- [ ] **Capability declarations updated** and the Part 3 §3 table sync test is green.
|
|
25
|
+
- [ ] **Rejected alternative named** in the description for design changes.
|
|
26
|
+
- [ ] **Attribution file regenerates cleanly** — the governance suite
|
|
27
|
+
(`tests/golden/test_corpus_governance.py`) is green.
|
|
28
|
+
- [ ] **Contributed files carry license grants** — for any file added under
|
|
29
|
+
`origin.kind: contributed`, I have the right to contribute it and grant it under the
|
|
30
|
+
recorded license (Apache-2.0 or a compatible data license).
|
|
31
|
+
- [ ] **Full local gate passed:** `ruff check .`, `ruff format --check .`, `mypy`,
|
|
32
|
+
`lint-imports`, `pytest`.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ci-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint-and-test:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
# 3.11 is the supported floor (catches use of newer syntax); 3.13 is the
|
|
19
|
+
# local dev interpreter (DECISIONS.md D11) — testing both keeps dev and CI
|
|
20
|
+
# from drifting.
|
|
21
|
+
python-version: ["3.11", "3.13"]
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
cache: pip
|
|
29
|
+
|
|
30
|
+
- name: Install
|
|
31
|
+
run: |
|
|
32
|
+
python -m pip install --upgrade pip
|
|
33
|
+
pip install -e ".[dev]"
|
|
34
|
+
|
|
35
|
+
- name: Ruff (lint)
|
|
36
|
+
run: ruff check .
|
|
37
|
+
|
|
38
|
+
- name: Ruff (format)
|
|
39
|
+
run: ruff format --check .
|
|
40
|
+
|
|
41
|
+
- name: Mypy
|
|
42
|
+
run: mypy
|
|
43
|
+
|
|
44
|
+
# Promoted to a required check in v0.2 M11 (Part 10 §1 deferral table, "earliest
|
|
45
|
+
# v0.2"): the import-linter contract from M0 confirmed as a blocking gate.
|
|
46
|
+
- name: Import-graph lint (P2)
|
|
47
|
+
run: lint-imports
|
|
48
|
+
|
|
49
|
+
# Install the example third-party plugin (M16B) so entry-point discovery is exercised
|
|
50
|
+
# against a real installed distribution — without it, tests/test_toyfmt_plugin.py skips.
|
|
51
|
+
# `--no-deps`: its declared `xtalate` dependency is already satisfied by the editable install
|
|
52
|
+
# above, and xtalate is not on any index yet (D52), so pip must not try to resolve it.
|
|
53
|
+
- name: Install entry-point discovery fixture (M16B)
|
|
54
|
+
run: pip install --no-deps ./tests/fixtures/xtalate_toyfmt
|
|
55
|
+
|
|
56
|
+
# Pytest enforces the coverage ratchet (--cov-fail-under in pyproject addopts) and the
|
|
57
|
+
# golden-corpus governance suite: manifest schema + license, per-source sha256, the
|
|
58
|
+
# schema-version migration-chain load, and the ATTRIBUTIONS.md regeneration diff
|
|
59
|
+
# (Part 8 §3; v0.2 M11). A silent fixture edit or a lapsed attribution fails here.
|
|
60
|
+
- name: Pytest (unit + golden + governance, with coverage gate)
|
|
61
|
+
run: pytest
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
name: nightly
|
|
2
|
+
|
|
3
|
+
# The scheduled companion to ci.yml (MASTER_SPEC Part 8 §5, Part 9 §3). The PR suite is capped near
|
|
4
|
+
# ten minutes; anything super-linear in formats or frames is deferred here, never dropped (M15B). A
|
|
5
|
+
# nightly failure opens an issue automatically rather than blocking anyone's PR — visible, tracked,
|
|
6
|
+
# not a surprise tax on unrelated work.
|
|
7
|
+
on:
|
|
8
|
+
schedule:
|
|
9
|
+
# 07:00 UTC daily — off the working day, well clear of PR-triggered runs.
|
|
10
|
+
- cron: "0 7 * * *"
|
|
11
|
+
workflow_dispatch: {}
|
|
12
|
+
|
|
13
|
+
# issues:write lets the failure step open the tracking issue; nothing else here needs write access.
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
issues: write
|
|
17
|
+
|
|
18
|
+
concurrency:
|
|
19
|
+
group: nightly
|
|
20
|
+
cancel-in-progress: false
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
nightly:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
|
|
28
|
+
# Single interpreter (3.13, the dev floor's upper leg, DECISIONS.md D11): the deferred work
|
|
29
|
+
# here — the matrix, benchmarks, extended properties, audit — is not interpreter-sensitive the
|
|
30
|
+
# way the syntax-floor guard is, so the 3.11×3.13 fan-out stays on the PR (ci.yml).
|
|
31
|
+
- uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.13"
|
|
34
|
+
cache: pip
|
|
35
|
+
|
|
36
|
+
- name: Install
|
|
37
|
+
run: |
|
|
38
|
+
python -m pip install --upgrade pip
|
|
39
|
+
pip install -e ".[dev]"
|
|
40
|
+
|
|
41
|
+
# Stage 1 — the full n×n round-trip matrix beyond the curated PR subset (Part 8 §2.4).
|
|
42
|
+
# XTALATE_FULL_MATRIX=1 un-gates the `nightly`-marked pairs (tests/conftest.py); `-m nightly`
|
|
43
|
+
# then runs *only* them — the curated high-risk pairs already ran on the PR, so re-running them
|
|
44
|
+
# here would be waste. --no-cov because the coverage ratchet is a PR gate: this deliberately
|
|
45
|
+
# narrow subset would never clear the --cov-fail-under floor, and coverage is not what nightly
|
|
46
|
+
# is measuring.
|
|
47
|
+
- name: Full round-trip matrix
|
|
48
|
+
env:
|
|
49
|
+
XTALATE_FULL_MATRIX: "1"
|
|
50
|
+
run: pytest -m nightly --no-cov
|
|
51
|
+
|
|
52
|
+
# Stage 2 — the performance corpus (Part 8 §4), measured not gated: a budget breach is
|
|
53
|
+
# reported, only a *crash* fails the step (non-zero exit). The >20% regression tripwire against
|
|
54
|
+
# a rolling median is deliberately NOT wired here — shared GitHub runners are too noisy for
|
|
55
|
+
# comparable timings; it activates on v0.5's pinned runner (harness docstring; slice plan 15C).
|
|
56
|
+
- name: Performance benchmarks
|
|
57
|
+
run: python -m benchmarks --out benchmark-results
|
|
58
|
+
|
|
59
|
+
# The wall-time + peak-RSS series (JSON + CSV) — the artifact a maintainer downloads to chart
|
|
60
|
+
# the trend by hand until the automated tripwire lands. always() so a benchmark crash still
|
|
61
|
+
# uploads whatever series was written before it.
|
|
62
|
+
- name: Upload benchmark series
|
|
63
|
+
if: always()
|
|
64
|
+
uses: actions/upload-artifact@v4
|
|
65
|
+
with:
|
|
66
|
+
name: benchmark-results
|
|
67
|
+
path: benchmark-results/
|
|
68
|
+
if-no-files-found: warn
|
|
69
|
+
|
|
70
|
+
# Stage 3 — the extended property run at the widened hypothesis budget (max_examples=2000).
|
|
71
|
+
# HYPOTHESIS_PROFILE=nightly selects the `nightly` profile registered in tests/conftest.py; the
|
|
72
|
+
# PR run caps the same suite at the cheap `pr` profile. --no-cov for the same reason as stage 1.
|
|
73
|
+
- name: Extended property tests
|
|
74
|
+
env:
|
|
75
|
+
HYPOTHESIS_PROFILE: nightly
|
|
76
|
+
run: pytest tests/property --no-cov
|
|
77
|
+
|
|
78
|
+
# Stage 4 — dependency vulnerability audit (Part 8 §5). Advisory, not blocking:
|
|
79
|
+
# continue-on-error keeps a fresh advisory against a pinned dependency visible (the step goes
|
|
80
|
+
# yellow) without failing the job or opening a spurious issue. pip-audit is a dev-extra.
|
|
81
|
+
- name: Dependency audit
|
|
82
|
+
continue-on-error: true
|
|
83
|
+
run: pip-audit
|
|
84
|
+
|
|
85
|
+
# A failure in the nightly job (a crashed benchmark, a red matrix, a broken property) opens a
|
|
86
|
+
# tracking issue — the "failures auto-open issues" of Part 9 §3, so the scheduled run is visible
|
|
87
|
+
# without anyone watching the Actions tab. The dependency audit is excluded by design (it is
|
|
88
|
+
# continue-on-error, so an advisory never reaches here). Its own failure is swallowed (`|| true`):
|
|
89
|
+
# the issue is a courtesy, never a second thing that can break the pipeline.
|
|
90
|
+
open-issue-on-failure:
|
|
91
|
+
needs: nightly
|
|
92
|
+
if: failure()
|
|
93
|
+
runs-on: ubuntu-latest
|
|
94
|
+
permissions:
|
|
95
|
+
contents: read
|
|
96
|
+
issues: write
|
|
97
|
+
steps:
|
|
98
|
+
- name: Open a tracking issue
|
|
99
|
+
env:
|
|
100
|
+
GH_TOKEN: ${{ github.token }}
|
|
101
|
+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
102
|
+
run: |
|
|
103
|
+
gh issue create --repo "${{ github.repository }}" \
|
|
104
|
+
--title "Nightly failure — $(date -u +%Y-%m-%d)" \
|
|
105
|
+
--body "The scheduled nightly workflow failed. Run: ${RUN_URL}" \
|
|
106
|
+
|| true
|