gp3sequencespy 0.1.2__tar.gz → 0.1.4__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.
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/workflows/create-stable-release.yml +11 -0
- gp3sequencespy-0.1.4/.github/workflows/publish-pypi.yml +151 -0
- gp3sequencespy-0.1.2/.hypothesis/constants/27ea81ecf5b94751 → gp3sequencespy-0.1.4/.hypothesis/constants/6490da55911cc2f9 +1 -1
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/CHANGELOG.md +47 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/CITATION.cff +2 -2
- gp3sequencespy-0.1.4/PKG-INFO +261 -0
- gp3sequencespy-0.1.4/PYPI_PUBLISHING.md +75 -0
- gp3sequencespy-0.1.4/README.md +205 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/RELEASE_CHECKLIST.md +4 -5
- gp3sequencespy-0.1.4/docs/assets/python-suite-logo.png +0 -0
- gp3sequencespy-0.1.4/docs/ecosystem-update-2026-09.md +25 -0
- gp3sequencespy-0.1.4/docs/index.md +192 -0
- gp3sequencespy-0.1.4/docs/release-readiness.md +58 -0
- gp3sequencespy-0.1.4/docs/stylesheets/home-refine.css +169 -0
- gp3sequencespy-0.1.4/docs/stylesheets/home.css +1172 -0
- gp3sequencespy-0.1.4/docs/validation-scope-methods-briefing.md +23 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/mkdocs.yml +12 -1
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/pyproject.toml +1 -1
- gp3sequencespy-0.1.4/reference/release_publication_0.1.2.json +67 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/404.html +113 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/choosing-a-sequence-analysis-method/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/consensus-and-group-comparisons/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/contiguous-motif-workflow/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/distances-clustering-and-stability/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/extended-sequence-visualisations/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/getting-started-with-gp3sequences/index.html +165 -42
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/index.html +166 -167
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/latent-models-and-optional-adapters/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/longitudinal-panel-sequences/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/multichannel-and-covariate-hmms/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/noncontiguous-subsequence-mining/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/reproducible-sequence-analysis-case-study/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/sequence-data-validation-and-preparation/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/sequence-inference-and-randomization/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/time-varying-condition-models/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/articles/transition-networks-and-higher-order-models/index.html +164 -41
- gp3sequencespy-0.1.4/site/assets/python-suite-logo.png +0 -0
- gp3sequencespy-0.1.4/site/ecosystem-update-2026-09/index.html +1711 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/examples/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/faq/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/index.html +310 -377
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/method-map/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/parity/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/plots/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/quality-completion/index.html +126 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/quickstart/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/r-to-python/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/reference/api/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/reference/index.html +164 -132
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/release-readiness/index.html +198 -57
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/reporting/index.html +164 -41
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/reproducibility/index.html +164 -41
- gp3sequencespy-0.1.4/site/search/search_index.json +1 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/sitemap.xml +38 -30
- gp3sequencespy-0.1.4/site/sitemap.xml.gz +0 -0
- gp3sequencespy-0.1.4/site/stylesheets/home-refine.css +169 -0
- gp3sequencespy-0.1.4/site/stylesheets/home.css +1172 -0
- gp3sequencespy-0.1.4/site/validation-scope-methods-briefing/index.html +1819 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/__init__.py +1 -1
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_docs_contract.py +9 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_release_contract.py +35 -3
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/uv.lock +1 -1
- gp3sequencespy-0.1.2/.github/workflows/publish-pypi.yml +0 -92
- gp3sequencespy-0.1.2/PKG-INFO +0 -107
- gp3sequencespy-0.1.2/PYPI_PUBLISHING.md +0 -70
- gp3sequencespy-0.1.2/README.md +0 -51
- gp3sequencespy-0.1.2/docs/index.md +0 -196
- gp3sequencespy-0.1.2/docs/release-readiness.md +0 -44
- gp3sequencespy-0.1.2/site/search/search_index.json +0 -1
- gp3sequencespy-0.1.2/site/sitemap.xml.gz +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/pull_request_template.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/workflows/ci.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/workflows/coverage-baseline.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/workflows/docs.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/workflows/quality-completion.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/workflows/quality-snapshot.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/workflows/release-check.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.github/workflows/verify-pypi.yml +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.gitignore +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/.gitignore +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/0ec322fbf26a61c7 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/16016a411c0ad329 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/17a46b7c9c102acf +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/2095120aae478f33 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/26f83342717945cb +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/32e07895177aa67c +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/389602d3cc162c76 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/3b1b3aaae56e612d +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/3df6cffc69e577b9 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/808d6cb89ee52f03 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/8a38b069589d1e28 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/ab29987832dd004b +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/b7c3765fa81698a2 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/d003c905b6045d79 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/d3ea6aefc5cc43fc +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/ed5356d05ebe0cd7 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/f07aa74bf328ec02 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/f25b4bdb464058c1 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/f85565f902aa91b6 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/fc1422370bb981d1 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/fd8b1ec617e7b1ea +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/.hypothesis/constants/ff602356a4e81123 +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/CODE_OF_CONDUCT.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/CONTRIBUTING.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/LICENSE +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/PARITY_EXCEPTIONS.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/PARITY_TEST_MATRIX.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/QUALITY_COMPLETION.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/REPRODUCIBILITY.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/SECURITY.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/SIGNATURE_PARITY.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/choosing-a-sequence-analysis-method.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/consensus-and-group-comparisons.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/contiguous-motif-workflow.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/distances-clustering-and-stability.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/extended-sequence-visualisations.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/getting-started-with-gp3sequences.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/index.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/latent-models-and-optional-adapters.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/longitudinal-panel-sequences.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/multichannel-and-covariate-hmms.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/noncontiguous-subsequence-mining.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/reproducible-sequence-analysis-case-study.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/sequence-data-validation-and-preparation.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/sequence-inference-and-randomization.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/time-varying-condition-models.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/articles/transition-networks-and-higher-order-models.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/assets/brand/gp3sequencespy-mark.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/assets/figures/distance-heatmap.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/assets/figures/sequence-index.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/assets/figures/state-distribution.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/assets/figures/transition-network.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/examples.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/faq.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/method-map.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/parity.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/plots.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/quality-completion.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/quickstart.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/r-to-python.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/reference/api.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/reference/index.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/reporting.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/reproducibility.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/docs/stylesheets/extra.css +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/README.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/__init__.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/actual/.gitkeep +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/canonicalizers/__init__.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/canonicalizers/csv_contracts.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/compare_oracle.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/expected/README.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/fixtures/minimal.csv +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/generate_python_outputs.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/r_scripts/generate_reference_outputs.R +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/parity/signature_audit.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/R_REFERENCE.md +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/api_manifest.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/article_manifest.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/oracle_validation.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/release_candidate_contract_0.1.0.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/release_publication_0.1.0.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/signature_parity_matrix.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/signatures.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/source_manifest.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/test_manifest.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/reference/test_parity_matrix.json +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/scripts/generate_coverage_ledger.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/scripts/run_mutation_smoke.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/_mkdocstrings.css +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/brand/gp3sequencespy-mark.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/figures/distance-heatmap.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/figures/sequence-index.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/figures/state-distribution.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/figures/transition-network.svg +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/images/favicon.png +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/bundle.d7400e89.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/bundle.d7400e89.min.js.map +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.ar.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.da.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.de.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.du.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.el.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.es.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.fi.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.fr.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.he.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.hi.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.hu.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.hy.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.it.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.ja.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.jp.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.kn.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.ko.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.multi.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.nl.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.no.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.pt.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.ro.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.ru.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.sa.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.sv.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.ta.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.te.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.th.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.tr.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.vi.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/min/lunr.zh.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/tinyseg.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/lunr/wordcut.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/workers/search.2c215733.min.js +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/javascripts/workers/search.2c215733.min.js.map +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/stylesheets/main.ec1eaa64.min.css +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/stylesheets/main.ec1eaa64.min.css.map +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/stylesheets/palette.ab4e12ef.min.css +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/assets/stylesheets/palette.ab4e12ef.min.css.map +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/objects.inv +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/site/stylesheets/extra.css +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/_advanced.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/_exceptions.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/_types.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/adapters.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/analysis_audit.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/capabilities.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/consensus.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/covariate_hmm.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/data.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/distances.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/hmm.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/inference.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/motif_visualisation.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/motifs.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/multichannel_hmm.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/networks.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/panel.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/py.typed +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/subsequences.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/summaries.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/time_models.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/src/gp3sequencespy/visualisations.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_advanced_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_analysis_audit_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_analysis_audit_final_branch.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_consensus_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_consensus_final_branches.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_core_port.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_covariate_hmm_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_data_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_distances_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_docs_examples_execute.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_hmm_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_inference_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_motif_visualisation_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_multichannel_hmm_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_multichannel_hmm_final_coverage.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_near_complete_coverage.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_networks_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_numpy_pandas_compat.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_optional_backend_contracts.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_panel_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_parity_harness.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_property_invariants.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_public_api.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_pyarrow_regression.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_quality_edge_contracts.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_r_advanced_deterministic_contracts.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_r_block_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_r_deterministic_contracts.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_r_hclust_oracle_regressions.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_r_remaining_contracts.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_remaining_r_api.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_residual_branch_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_signature_parity.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_subsequences_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_time_models_completion.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_time_mssm_backend.py +0 -0
- {gp3sequencespy-0.1.2 → gp3sequencespy-0.1.4}/tests/test_visualisations_completion.py +0 -0
|
@@ -12,6 +12,7 @@ on:
|
|
|
12
12
|
|
|
13
13
|
permissions:
|
|
14
14
|
contents: write
|
|
15
|
+
actions: write
|
|
15
16
|
|
|
16
17
|
jobs:
|
|
17
18
|
release:
|
|
@@ -196,3 +197,13 @@ jobs:
|
|
|
196
197
|
--verify-tag \
|
|
197
198
|
--title "gp3sequencespy $VERSION" \
|
|
198
199
|
--notes-file release-notes.md
|
|
200
|
+
|
|
201
|
+
- name: Trigger exact-artifact Trusted Publishing
|
|
202
|
+
shell: bash
|
|
203
|
+
env:
|
|
204
|
+
GH_TOKEN: ${{ github.token }}
|
|
205
|
+
run: |
|
|
206
|
+
gh workflow run publish-pypi.yml \
|
|
207
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
208
|
+
--ref main \
|
|
209
|
+
-f "tag=$TAG"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
tag:
|
|
9
|
+
description: Existing stable GitHub Release tag to publish, for example v0.1.2
|
|
10
|
+
required: true
|
|
11
|
+
type: string
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
verify-release-assets:
|
|
18
|
+
name: Verify release distributions
|
|
19
|
+
if: >-
|
|
20
|
+
(github.event_name == 'release' && github.event.release.draft == false && github.event.release.prerelease == false) ||
|
|
21
|
+
github.event_name == 'workflow_dispatch'
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
outputs:
|
|
24
|
+
tag: ${{ steps.target.outputs.tag }}
|
|
25
|
+
steps:
|
|
26
|
+
- name: Resolve stable release tag
|
|
27
|
+
id: target
|
|
28
|
+
shell: bash
|
|
29
|
+
env:
|
|
30
|
+
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
31
|
+
DISPATCH_TAG: ${{ inputs.tag }}
|
|
32
|
+
run: |
|
|
33
|
+
case "$GITHUB_EVENT_NAME" in
|
|
34
|
+
release)
|
|
35
|
+
TAG="$RELEASE_TAG"
|
|
36
|
+
;;
|
|
37
|
+
workflow_dispatch)
|
|
38
|
+
TAG="$DISPATCH_TAG"
|
|
39
|
+
;;
|
|
40
|
+
*)
|
|
41
|
+
echo "unsupported event: $GITHUB_EVENT_NAME" >&2
|
|
42
|
+
exit 1
|
|
43
|
+
;;
|
|
44
|
+
esac
|
|
45
|
+
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
46
|
+
echo "stable vX.Y.Z tag required, got $TAG" >&2
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
50
|
+
echo "Publishing exact GitHub Release assets for $TAG"
|
|
51
|
+
|
|
52
|
+
- name: Require published stable GitHub Release
|
|
53
|
+
shell: bash
|
|
54
|
+
env:
|
|
55
|
+
GH_TOKEN: ${{ github.token }}
|
|
56
|
+
TAG: ${{ steps.target.outputs.tag }}
|
|
57
|
+
run: |
|
|
58
|
+
gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json tagName,isDraft,isPrerelease > release.json
|
|
59
|
+
TAG="$TAG" python - <<'PY'
|
|
60
|
+
import json
|
|
61
|
+
import os
|
|
62
|
+
release = json.load(open('release.json', encoding='utf-8'))
|
|
63
|
+
assert release['tagName'] == os.environ['TAG']
|
|
64
|
+
assert release['isDraft'] is False
|
|
65
|
+
assert release['isPrerelease'] is False
|
|
66
|
+
print('stable GitHub Release: PASS', release['tagName'])
|
|
67
|
+
PY
|
|
68
|
+
|
|
69
|
+
- name: Download exact GitHub Release distributions and checksums
|
|
70
|
+
shell: bash
|
|
71
|
+
env:
|
|
72
|
+
GH_TOKEN: ${{ github.token }}
|
|
73
|
+
TAG: ${{ steps.target.outputs.tag }}
|
|
74
|
+
run: |
|
|
75
|
+
mkdir -p dist
|
|
76
|
+
gh release download "$TAG" \
|
|
77
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
78
|
+
--pattern "gp3sequencespy-*.whl" \
|
|
79
|
+
--pattern "gp3sequencespy-*.tar.gz" \
|
|
80
|
+
--pattern "SHA256SUMS.txt" \
|
|
81
|
+
--dir dist
|
|
82
|
+
|
|
83
|
+
- name: Require exact checksums and filenames matching stable tag
|
|
84
|
+
shell: bash
|
|
85
|
+
env:
|
|
86
|
+
TAG: ${{ steps.target.outputs.tag }}
|
|
87
|
+
run: |
|
|
88
|
+
cd dist
|
|
89
|
+
sha256sum --check SHA256SUMS.txt
|
|
90
|
+
cd ..
|
|
91
|
+
python - <<'PY'
|
|
92
|
+
import glob
|
|
93
|
+
import os
|
|
94
|
+
import re
|
|
95
|
+
|
|
96
|
+
wheels = glob.glob('dist/*.whl')
|
|
97
|
+
sdists = glob.glob('dist/*.tar.gz')
|
|
98
|
+
if len(wheels) != 1 or len(sdists) != 1:
|
|
99
|
+
raise SystemExit(f'expected one wheel and one sdist; got {wheels=} {sdists=}')
|
|
100
|
+
|
|
101
|
+
tag = os.environ['TAG']
|
|
102
|
+
if not re.fullmatch(r'v\d+\.\d+\.\d+', tag):
|
|
103
|
+
raise SystemExit(f'stable release tag required, got {tag!r}')
|
|
104
|
+
|
|
105
|
+
version = tag[1:]
|
|
106
|
+
expected_wheel = f'dist/gp3sequencespy-{version}-py3-none-any.whl'
|
|
107
|
+
expected_sdist = f'dist/gp3sequencespy-{version}.tar.gz'
|
|
108
|
+
if wheels[0].replace('\\', '/') != expected_wheel:
|
|
109
|
+
raise SystemExit(f'wheel filename does not match release tag: {wheels[0]!r}')
|
|
110
|
+
if sdists[0].replace('\\', '/') != expected_sdist:
|
|
111
|
+
raise SystemExit(f'sdist filename does not match release tag: {sdists[0]!r}')
|
|
112
|
+
print('release filenames and checksums match stable tag', tag)
|
|
113
|
+
PY
|
|
114
|
+
|
|
115
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
116
|
+
with:
|
|
117
|
+
python-version: "3.13"
|
|
118
|
+
|
|
119
|
+
- name: Validate release distributions
|
|
120
|
+
run: uv tool run --from twine==7.0.0 twine check --strict dist/*.whl dist/*.tar.gz
|
|
121
|
+
|
|
122
|
+
- name: Upload verified distributions for publish job
|
|
123
|
+
uses: actions/upload-artifact@v7.0.1
|
|
124
|
+
with:
|
|
125
|
+
name: verified-pypi-distributions
|
|
126
|
+
path: |
|
|
127
|
+
dist/gp3sequencespy-*.whl
|
|
128
|
+
dist/gp3sequencespy-*.tar.gz
|
|
129
|
+
if-no-files-found: error
|
|
130
|
+
retention-days: 7
|
|
131
|
+
|
|
132
|
+
pypi-publish:
|
|
133
|
+
name: Publish verified distributions
|
|
134
|
+
needs: verify-release-assets
|
|
135
|
+
if: needs.verify-release-assets.result == 'success'
|
|
136
|
+
runs-on: ubuntu-latest
|
|
137
|
+
environment:
|
|
138
|
+
name: pypi
|
|
139
|
+
url: https://pypi.org/project/gp3sequencespy/
|
|
140
|
+
permissions:
|
|
141
|
+
id-token: write
|
|
142
|
+
|
|
143
|
+
steps:
|
|
144
|
+
- name: Download verified distributions
|
|
145
|
+
uses: actions/download-artifact@v8.0.1
|
|
146
|
+
with:
|
|
147
|
+
name: verified-pypi-distributions
|
|
148
|
+
path: dist
|
|
149
|
+
|
|
150
|
+
- name: Publish package distributions to PyPI
|
|
151
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
# file: /home/runner/work/gp3sequencespy/gp3sequencespy/src/gp3sequencespy/__init__.py
|
|
2
2
|
# hypothesis_version: 6.165.10
|
|
3
3
|
|
|
4
|
-
['0.1.
|
|
4
|
+
['0.1.4', 'CovariateSequenceHMM', 'GP3SequencesError', 'GrpStringInput', 'ModelFitError', 'MotifPositionResult', 'ParityError', 'ValidationError', 'WideSequenceAdapter', 'as_arules_sequences', 'as_grpstring_data', 'as_seqhmm_sequences', 'audit_sequence_data', 'cluster_sequences', 'encode_sequence_data', 'fit_sequence_hmm', 'plot_sequence_index', 'plot_sequence_motifs', 'predict_next_state']
|
|
@@ -7,6 +7,53 @@ All notable changes to `gp3sequencespy` are documented here. The project follows
|
|
|
7
7
|
|
|
8
8
|
No changes yet.
|
|
9
9
|
|
|
10
|
+
## [0.1.4] - 2026-10-09
|
|
11
|
+
|
|
12
|
+
*Documentation-only maintenance candidate.*
|
|
13
|
+
|
|
14
|
+
### Documentation
|
|
15
|
+
|
|
16
|
+
- Integrate the reviewed methods-briefing guide on estimation-visualization boundaries for participant-level scalar sequence summaries versus transition, HMM and other structured estimands.
|
|
17
|
+
- Keep all underlying scientific implementation and the frozen 81-API/R parity surface unchanged; do not advertise new experimental methods.
|
|
18
|
+
- Require existing frozen parity, exact coverage, mutation smoke, strict documentation, fresh wheel, immutable release-asset checks, and trusted PyPI publication gates to pass before publishing.
|
|
19
|
+
|
|
20
|
+
## [0.1.3] - 2026-09-21
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Hardened exact-artifact GitHub Release to PyPI Trusted Publishing,
|
|
25
|
+
including guarded stable-release verification, filename checks,
|
|
26
|
+
checksum verification, and explicit manual-dispatch support.
|
|
27
|
+
- Refined stable-release orchestration so GitHub Release distributions
|
|
28
|
+
remain the authoritative artifacts consumed by PyPI without rebuilding.
|
|
29
|
+
- Redesigned and refined the public MkDocs homepage, navigation, visual
|
|
30
|
+
system, repository front page, and shared Python Suite branding.
|
|
31
|
+
- Added the September 2026 ecosystem methods update and strengthened the
|
|
32
|
+
documentation rendering contract.
|
|
33
|
+
|
|
34
|
+
### Validation
|
|
35
|
+
|
|
36
|
+
- **293 / 293** Python tests pass on the certified pre-release tree.
|
|
37
|
+
- **4,564 / 4,564** executable statements are covered (**100.00%**).
|
|
38
|
+
- **1,702 / 1,702** branches are covered (**100.00%**).
|
|
39
|
+
- Mutation smoke remains **3 / 3 killed**.
|
|
40
|
+
- Frozen API remains **81 / 81**.
|
|
41
|
+
- Frozen R test-block ledger remains **130 / 130**.
|
|
42
|
+
- Frozen public signatures remain **81 / 81** with **0 unexplained drift**.
|
|
43
|
+
- Local Ruff, mypy, strict MkDocs, wheel/sdist build, Twine validation,
|
|
44
|
+
clean wheel installation, and clean sdist installation pass.
|
|
45
|
+
|
|
46
|
+
### Scientific/API status
|
|
47
|
+
|
|
48
|
+
- No scientific implementation files under `src/gp3sequencespy` changed
|
|
49
|
+
between `v0.1.2` and the 0.1.3 release preparation tree except the
|
|
50
|
+
required package version string.
|
|
51
|
+
- No breaking scientific API or public-signature change is introduced.
|
|
52
|
+
- The frozen `gp3sequences` 0.3.0 behavioral reference remains unchanged.
|
|
53
|
+
- The twelve additional names in Python `__all__` remain deliberate
|
|
54
|
+
Python public classes, exceptions, adapters, and audit objects outside
|
|
55
|
+
the frozen 81-function R parity manifest.
|
|
56
|
+
|
|
10
57
|
## [0.1.2] - 2026-08-31
|
|
11
58
|
|
|
12
59
|
### Added
|
|
@@ -7,8 +7,8 @@ type: software
|
|
|
7
7
|
authors:
|
|
8
8
|
- family-names: Balaskas
|
|
9
9
|
given-names: Stefanos
|
|
10
|
-
version: 0.1.
|
|
11
|
-
date-released: 2026-
|
|
10
|
+
version: 0.1.4
|
|
11
|
+
date-released: 2026-10-09
|
|
12
12
|
license: MIT
|
|
13
13
|
repository-code: https://github.com/stefanosbalaskas/gp3sequencespy
|
|
14
14
|
url: https://stefanosbalaskas.github.io/gp3sequencespy/
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: gp3sequencespy
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Summary: Transparent, reproducible, and auditable analysis of ordered categorical sequences in Python.
|
|
5
|
+
Project-URL: Homepage, https://stefanosbalaskas.github.io/gp3sequencespy/
|
|
6
|
+
Project-URL: Documentation, https://stefanosbalaskas.github.io/gp3sequencespy/
|
|
7
|
+
Project-URL: Source, https://github.com/stefanosbalaskas/gp3sequencespy
|
|
8
|
+
Project-URL: Issues, https://github.com/stefanosbalaskas/gp3sequencespy/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/stefanosbalaskas/gp3sequencespy/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Archive, https://doi.org/10.5281/zenodo.22166449
|
|
11
|
+
Author: Stefanos Balaskas
|
|
12
|
+
Maintainer: Stefanos Balaskas
|
|
13
|
+
License-Expression: MIT
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Keywords: categorical-sequences,eye-tracking,reproducibility,scanpaths,sequence-analysis
|
|
16
|
+
Classifier: Development Status :: 4 - Beta
|
|
17
|
+
Classifier: Intended Audience :: Science/Research
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
26
|
+
Requires-Python: >=3.11
|
|
27
|
+
Requires-Dist: matplotlib>=3.8
|
|
28
|
+
Requires-Dist: networkx>=3.2
|
|
29
|
+
Requires-Dist: numpy>=1.26
|
|
30
|
+
Requires-Dist: pandas>=2.1
|
|
31
|
+
Requires-Dist: scipy>=1.11
|
|
32
|
+
Provides-Extra: data
|
|
33
|
+
Requires-Dist: polars>=1; extra == 'data'
|
|
34
|
+
Requires-Dist: pyarrow>=17; extra == 'data'
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
37
|
+
Requires-Dist: hypothesis>=6; extra == 'dev'
|
|
38
|
+
Requires-Dist: mypy>=1.15; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
41
|
+
Requires-Dist: ruff>=0.12; extra == 'dev'
|
|
42
|
+
Provides-Extra: docs
|
|
43
|
+
Requires-Dist: mkdocs-material>=9.6; extra == 'docs'
|
|
44
|
+
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
45
|
+
Requires-Dist: mkdocstrings[python]>=0.29; extra == 'docs'
|
|
46
|
+
Provides-Extra: hmm
|
|
47
|
+
Requires-Dist: hmmlearn>=0.3.3; extra == 'hmm'
|
|
48
|
+
Provides-Extra: performance
|
|
49
|
+
Requires-Dist: numba>=0.61; extra == 'performance'
|
|
50
|
+
Provides-Extra: release
|
|
51
|
+
Requires-Dist: twine>=6; extra == 'release'
|
|
52
|
+
Requires-Dist: validate-pyproject>=0.24; extra == 'release'
|
|
53
|
+
Provides-Extra: time
|
|
54
|
+
Requires-Dist: mssm<1.3,>=1.2.5; extra == 'time'
|
|
55
|
+
Description-Content-Type: text/markdown
|
|
56
|
+
|
|
57
|
+
<p align="center">
|
|
58
|
+
<img src="https://raw.githubusercontent.com/stefanosbalaskas/gp3sequencespy/main/docs/assets/python-suite-logo.png" width="260" alt="Python Suite research packages logo">
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
<h1 align="center">gp3sequencespy</h1>
|
|
62
|
+
|
|
63
|
+
<p align="center">
|
|
64
|
+
<strong>Transparent, reproducible sequence analysis in Python.</strong><br>
|
|
65
|
+
Audit ordered categorical data, discover recurring structure, compare trajectories,
|
|
66
|
+
model transitions and latent states, test group differences, and report every analytical choice.
|
|
67
|
+
</p>
|
|
68
|
+
|
|
69
|
+
<p align="center">
|
|
70
|
+
<a href="https://pypi.org/project/gp3sequencespy/"><img alt="PyPI" src="https://img.shields.io/pypi/v/gp3sequencespy?logo=pypi&logoColor=white"></a>
|
|
71
|
+
<a href="https://pypi.org/project/gp3sequencespy/"><img alt="Python versions" src="https://img.shields.io/pypi/pyversions/gp3sequencespy?logo=python&logoColor=white"></a>
|
|
72
|
+
<a href="https://github.com/stefanosbalaskas/gp3sequencespy/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/stefanosbalaskas/gp3sequencespy/actions/workflows/ci.yml/badge.svg?branch=main"></a>
|
|
73
|
+
<a href="https://github.com/stefanosbalaskas/gp3sequencespy/actions/workflows/docs.yml"><img alt="Docs" src="https://github.com/stefanosbalaskas/gp3sequencespy/actions/workflows/docs.yml/badge.svg?branch=main"></a>
|
|
74
|
+
<a href="https://github.com/stefanosbalaskas/gp3sequencespy/actions/workflows/quality-completion.yml"><img alt="Quality" src="https://github.com/stefanosbalaskas/gp3sequencespy/actions/workflows/quality-completion.yml/badge.svg?branch=main"></a>
|
|
75
|
+
<a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-4c1.svg"></a>
|
|
76
|
+
<a href="https://doi.org/10.5281/zenodo.22166449"><img alt="DOI" src="https://zenodo.org/badge/DOI/10.5281/zenodo.22166449.svg"></a>
|
|
77
|
+
</p>
|
|
78
|
+
|
|
79
|
+
<p align="center">
|
|
80
|
+
<a href="https://stefanosbalaskas.github.io/gp3sequencespy/"><strong>Documentation</strong></a>
|
|
81
|
+
· <a href="https://stefanosbalaskas.github.io/gp3sequencespy/quickstart/">Quickstart</a>
|
|
82
|
+
· <a href="https://stefanosbalaskas.github.io/gp3sequencespy/method-map/">Method map</a>
|
|
83
|
+
· <a href="https://stefanosbalaskas.github.io/gp3sequencespy/plots/">Plot gallery</a>
|
|
84
|
+
· <a href="https://stefanosbalaskas.github.io/gp3sequencespy/reference/">API reference</a>
|
|
85
|
+
· <a href="https://github.com/stefanosbalaskas/gp3sequencespy/releases/tag/v0.1.4">v0.1.4</a>
|
|
86
|
+
</p>
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
`gp3sequencespy` is the Python implementation of **gp3sequences 0.3.0** for ordered categorical sequences and scanpaths. The frozen R 0.3.0 tarball is the behavioral reference: scientific contracts are preserved and tested explicitly, while deliberate R→Python translations are documented rather than hidden.
|
|
91
|
+
|
|
92
|
+
The package is designed for research workflows where **data preparation, method choice, reproducibility, and interpretation need to remain visible from input to report**.
|
|
93
|
+
|
|
94
|
+
## Install
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pip install gp3sequencespy==0.1.4
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
With `uv`:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
uv add gp3sequencespy==0.1.4
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Python **3.11–3.14** is supported. Optional extras are available for HMM backends, Arrow/Polars data interoperability, performance helpers, time-varying models, documentation, and development.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pip install "gp3sequencespy[hmm]"
|
|
110
|
+
pip install "gp3sequencespy[data]"
|
|
111
|
+
pip install "gp3sequencespy[time]"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## A 60-second workflow
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
import pandas as pd
|
|
118
|
+
import gp3sequencespy as g
|
|
119
|
+
|
|
120
|
+
# One row per observed state occurrence.
|
|
121
|
+
data = pd.DataFrame(
|
|
122
|
+
{
|
|
123
|
+
"sequence_id": ["s1", "s1", "s1", "s2", "s2", "s2"],
|
|
124
|
+
"sequence_order": [1, 2, 3, 1, 2, 3],
|
|
125
|
+
"state": ["home", "search", "checkout", "home", "product", "checkout"],
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Audit and prepare explicitly.
|
|
130
|
+
validation = g.validate_sequence_data(
|
|
131
|
+
data,
|
|
132
|
+
"sequence_id",
|
|
133
|
+
"sequence_order",
|
|
134
|
+
"state",
|
|
135
|
+
)
|
|
136
|
+
prepared = g.prepare_sequence_data(
|
|
137
|
+
data,
|
|
138
|
+
"sequence_id",
|
|
139
|
+
"sequence_order",
|
|
140
|
+
"state",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Compare complete trajectories.
|
|
144
|
+
distance = g.compute_sequence_distance(
|
|
145
|
+
prepared.data,
|
|
146
|
+
method="lcs",
|
|
147
|
+
normalise="max_length",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Inspect transition structure.
|
|
151
|
+
network = g.create_transition_network(
|
|
152
|
+
prepared.data,
|
|
153
|
+
normalise="from",
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Visualise complete paths.
|
|
157
|
+
ax = g.plot_sequence_index(prepared.data)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
For the complete path from raw long-format data to summaries, motifs, clustering, networks, plots, and analysis auditing, see the **[Quickstart](https://stefanosbalaskas.github.io/gp3sequencespy/quickstart/)**.
|
|
161
|
+
|
|
162
|
+
## What you can do
|
|
163
|
+
|
|
164
|
+
| Research task | Capabilities | Start here |
|
|
165
|
+
| --- | --- | --- |
|
|
166
|
+
| **Audit & prepare** | ordering, missing states, duplicate positions, durations, state policies, preparation provenance | [Validation & preparation](https://stefanosbalaskas.github.io/gp3sequencespy/articles/sequence-data-validation-and-preparation/) |
|
|
167
|
+
| **Describe sequences** | state occupancy, transitions, paths, consensus, representatives | [Examples](https://stefanosbalaskas.github.io/gp3sequencespy/examples/) |
|
|
168
|
+
| **Find recurring structure** | contiguous motifs, bounded non-contiguous subsequences, motif filtering and visualisation | [Motif workflow](https://stefanosbalaskas.github.io/gp3sequencespy/articles/contiguous-motif-workflow/) |
|
|
169
|
+
| **Compare trajectories** | Levenshtein, LCS, optimal matching, transition-profile distances, clustering and stability | [Distances & clustering](https://stefanosbalaskas.github.io/gp3sequencespy/articles/distances-clustering-and-stability/) |
|
|
170
|
+
| **Model transitions** | transition networks, centrality, communities, higher-order transition structure | [Networks & higher-order models](https://stefanosbalaskas.github.io/gp3sequencespy/articles/transition-networks-and-higher-order-models/) |
|
|
171
|
+
| **Fit latent models** | categorical, multichannel, covariate-dependent and time-varying HMM workflows | [Latent models](https://stefanosbalaskas.github.io/gp3sequencespy/articles/latent-models-and-optional-adapters/) |
|
|
172
|
+
| **Test group structure** | design-aware randomization and sequence-group inference | [Inference & randomization](https://stefanosbalaskas.github.io/gp3sequencespy/articles/sequence-inference-and-randomization/) |
|
|
173
|
+
| **Visualise & report** | sequence index, state distributions, distance heatmaps, transition networks, audit trails | [Plot gallery](https://stefanosbalaskas.github.io/gp3sequencespy/plots/) |
|
|
174
|
+
|
|
175
|
+
Not sure which family fits your question? Use the **[method map](https://stefanosbalaskas.github.io/gp3sequencespy/method-map/)** to move from research question → assumptions → method family.
|
|
176
|
+
|
|
177
|
+
## Parity and validation
|
|
178
|
+
|
|
179
|
+
Version **0.1.4** is a maintenance release preserving the 0.1.2 scientific contracts while strengthening release automation and public documentation.
|
|
180
|
+
|
|
181
|
+
| Validation contract | Status |
|
|
182
|
+
| --- | ---: |
|
|
183
|
+
| Frozen R public counterparts | **81 / 81** |
|
|
184
|
+
| Frozen R public signatures audited | **81 / 81** |
|
|
185
|
+
| Frozen R `test_that()` blocks translated | **130 / 130** |
|
|
186
|
+
| Python tests | **293** |
|
|
187
|
+
| Statement coverage | **100%** |
|
|
188
|
+
| Branch coverage | **100%** |
|
|
189
|
+
| Mutation smoke | **3 / 3 killed** |
|
|
190
|
+
| CI platforms | **Linux · macOS · Windows** |
|
|
191
|
+
| CI Python versions | **3.11 · 3.12 · 3.13 · 3.14** |
|
|
192
|
+
| Python-native articles | **15** |
|
|
193
|
+
|
|
194
|
+
The deterministic core, hierarchical/PAM, and time-varying-model cross-language oracle tranches have been executed against frozen R 0.3.0. Remaining deliberate boundaries are recorded in [`PARITY_EXCEPTIONS.md`](PARITY_EXCEPTIONS.md), with broader parity evidence in [`PARITY_TEST_MATRIX.md`](PARITY_TEST_MATRIX.md) and the [online parity guide](https://stefanosbalaskas.github.io/gp3sequencespy/parity/).
|
|
195
|
+
|
|
196
|
+
## Documentation routes
|
|
197
|
+
|
|
198
|
+
| If you want to… | Go to |
|
|
199
|
+
| --- | --- |
|
|
200
|
+
| get from install to first analysis quickly | [Quickstart](https://stefanosbalaskas.github.io/gp3sequencespy/quickstart/) |
|
|
201
|
+
| choose a method by research question | [Method map](https://stefanosbalaskas.github.io/gp3sequencespy/method-map/) |
|
|
202
|
+
| copy complete analysis recipes | [Examples](https://stefanosbalaskas.github.io/gp3sequencespy/examples/) |
|
|
203
|
+
| inspect available figure families | [Plot gallery](https://stefanosbalaskas.github.io/gp3sequencespy/plots/) |
|
|
204
|
+
| read the full methodological guides | [Articles](https://stefanosbalaskas.github.io/gp3sequencespy/articles/) |
|
|
205
|
+
| translate from the R package | [R → Python](https://stefanosbalaskas.github.io/gp3sequencespy/r-to-python/) |
|
|
206
|
+
| browse functions and signatures | [API reference](https://stefanosbalaskas.github.io/gp3sequencespy/reference/) |
|
|
207
|
+
| document a reproducible analysis | [Reproducibility](https://stefanosbalaskas.github.io/gp3sequencespy/reproducibility/) · [Reporting guide](https://stefanosbalaskas.github.io/gp3sequencespy/reporting/) |
|
|
208
|
+
|
|
209
|
+
## Reproducibility and release governance
|
|
210
|
+
|
|
211
|
+
The package treats release and parity evidence as part of the scientific software contract.
|
|
212
|
+
|
|
213
|
+
- [`REPRODUCIBILITY.md`](REPRODUCIBILITY.md) — frozen-reference and reproducibility policy
|
|
214
|
+
- [`PARITY_EXCEPTIONS.md`](PARITY_EXCEPTIONS.md) — deliberate R→Python boundaries
|
|
215
|
+
- [`SIGNATURE_PARITY.md`](SIGNATURE_PARITY.md) — frozen public-signature audit
|
|
216
|
+
- [`QUALITY_COMPLETION.md`](QUALITY_COMPLETION.md) — 100% coverage and mutation-hardening evidence
|
|
217
|
+
- [`RELEASE_CHECKLIST.md`](RELEASE_CHECKLIST.md) — stable-release gates
|
|
218
|
+
- [`PYPI_PUBLISHING.md`](PYPI_PUBLISHING.md) — Trusted Publishing and artifact verification
|
|
219
|
+
- [`CHANGELOG.md`](CHANGELOG.md) — release history
|
|
220
|
+
|
|
221
|
+
Stable releases publish the exact validated GitHub Release wheel and source distribution to PyPI through GitHub OIDC Trusted Publishing. Each publication is subsequently checked against the GitHub Release SHA-256 hashes and with a clean PyPI installation.
|
|
222
|
+
|
|
223
|
+
## Development
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
uv sync --all-extras --python 3.12
|
|
227
|
+
uv run pytest -q
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Full quality gate:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
uv run pytest -q \
|
|
234
|
+
--cov=gp3sequencespy \
|
|
235
|
+
--cov-branch \
|
|
236
|
+
--cov-report=term-missing \
|
|
237
|
+
--cov-fail-under=100
|
|
238
|
+
|
|
239
|
+
uv run python scripts/run_mutation_smoke.py
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for contribution guidance and [`SECURITY.md`](SECURITY.md) for the security policy.
|
|
243
|
+
|
|
244
|
+
## Citation
|
|
245
|
+
|
|
246
|
+
If `gp3sequencespy` contributes to your research, use the repository citation metadata in [`CITATION.cff`](CITATION.cff) and the archived Zenodo record:
|
|
247
|
+
|
|
248
|
+
**DOI: [10.5281/zenodo.22166449](https://doi.org/10.5281/zenodo.22166449)**
|
|
249
|
+
|
|
250
|
+
## Scientific interpretation guardrail
|
|
251
|
+
|
|
252
|
+
> Sequence structure does not independently establish emotion, cognition, comprehension, personality, intention, deception, diagnosis, or causality. Observational group contrasts are associational unless a valid randomized design supports a causal interpretation.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
<p align="center">
|
|
257
|
+
<a href="https://stefanosbalaskas.github.io/gp3sequencespy/">Documentation</a>
|
|
258
|
+
· <a href="https://pypi.org/project/gp3sequencespy/">PyPI</a>
|
|
259
|
+
· <a href="https://github.com/stefanosbalaskas/gp3sequencespy/releases">Releases</a>
|
|
260
|
+
· <a href="https://doi.org/10.5281/zenodo.22166449">Zenodo</a>
|
|
261
|
+
</p>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# PyPI publishing
|
|
2
|
+
|
|
3
|
+
`gp3sequencespy` uses exact-artifact publication: stable wheel and source distributions are first built, validated, checksummed, and attached to a GitHub Release, then those same files are published to PyPI without rebuilding.
|
|
4
|
+
|
|
5
|
+
## 0.1.0 publication identity
|
|
6
|
+
|
|
7
|
+
- Git commit: `28f06a571889bf9db760d00c47e1252d3836679a`
|
|
8
|
+
- Git tag: `v0.1.0`
|
|
9
|
+
- Wheel: `gp3sequencespy-0.1.0-py3-none-any.whl`
|
|
10
|
+
- Wheel SHA-256: `97725d0b34872b79c9f9cb4da57f14a788a8920880a0a415c13669d281a39525`
|
|
11
|
+
- Source distribution: `gp3sequencespy-0.1.0.tar.gz`
|
|
12
|
+
- Source SHA-256: `e01ff3ac4ec0cbede48b1019e4bcabddd38b9587df3fe541ce66aff585bf7e19`
|
|
13
|
+
|
|
14
|
+
PyPI's JSON API was queried after upload and both published hashes matched the frozen GitHub Release artifacts exactly.
|
|
15
|
+
|
|
16
|
+
## 0.1.2 publication identity
|
|
17
|
+
|
|
18
|
+
Version **0.1.2** was published on 2026-08-31 through PyPI Trusted Publishing after the complete quality-completion release gate passed.
|
|
19
|
+
|
|
20
|
+
- Release commit: `564dfb3f97dde9e9228819bf4792821584b02934`
|
|
21
|
+
- Annotated tag: `v0.1.2`
|
|
22
|
+
- Annotated tag object: `c2ee786031c0badb9127529601e08893e90af70d`
|
|
23
|
+
- GitHub Release ID: `379432726`
|
|
24
|
+
- Wheel: `gp3sequencespy-0.1.2-py3-none-any.whl`
|
|
25
|
+
- Wheel SHA-256: `3fd063414f0c8c37fb5ae9a6aacf103a89afd0e6e2135ab3b81248b38b9ba847`
|
|
26
|
+
- Source distribution: `gp3sequencespy-0.1.2.tar.gz`
|
|
27
|
+
- Source SHA-256: `58b5e81149accf95d1b1a7e205f8cdf7a21846f0138b8aae00cfddd5db4289d9`
|
|
28
|
+
- Stable-release workflow run: `33342028606` — **PASS**
|
|
29
|
+
- Trusted Publishing workflow run: `33342198803` — **PASS**
|
|
30
|
+
- Post-PyPI verification run: `33342235019` — **PASS**
|
|
31
|
+
- Verification artifact: `9740897782`
|
|
32
|
+
|
|
33
|
+
The independent verifier compared the GitHub Release SHA-256 values against PyPI's published-file SHA-256 values and confirmed exact equality for both distributions. It then created a clean virtual environment and successfully installed `gp3sequencespy==0.1.2` from PyPI.
|
|
34
|
+
|
|
35
|
+
The full machine-readable publication ledger is stored in `reference/release_publication_0.1.2.json`.
|
|
36
|
+
|
|
37
|
+
## Trusted Publishing
|
|
38
|
+
|
|
39
|
+
The PyPI project has an active GitHub Actions Trusted Publisher for `.github/workflows/publish-pypi.yml` using the `pypi` environment.
|
|
40
|
+
|
|
41
|
+
### Active PyPI configuration
|
|
42
|
+
|
|
43
|
+
- **Owner:** `stefanosbalaskas`
|
|
44
|
+
- **Repository:** `gp3sequencespy`
|
|
45
|
+
- **Workflow name:** `publish-pypi.yml`
|
|
46
|
+
- **Environment name:** `pypi`
|
|
47
|
+
|
|
48
|
+
The publishing job alone receives `id-token: write`; no long-lived PyPI credential is required by the automated path.
|
|
49
|
+
|
|
50
|
+
### Release behavior
|
|
51
|
+
|
|
52
|
+
The permanent workflow supports two guarded entry points:
|
|
53
|
+
|
|
54
|
+
1. a published stable GitHub Release; or
|
|
55
|
+
2. an explicit manual dispatch naming an existing stable `vX.Y.Z` GitHub Release.
|
|
56
|
+
|
|
57
|
+
The manual-dispatch path exists because GitHub intentionally suppresses workflow chaining when one workflow creates a Release using `GITHUB_TOKEN`.
|
|
58
|
+
|
|
59
|
+
For either entry point the verification job:
|
|
60
|
+
|
|
61
|
+
1. resolves and validates the stable `vX.Y.Z` tag;
|
|
62
|
+
2. requires an existing non-draft, non-prerelease GitHub Release;
|
|
63
|
+
3. downloads the exact wheel, sdist, and `SHA256SUMS.txt` attached to that Release;
|
|
64
|
+
4. verifies the release checksums;
|
|
65
|
+
5. requires filenames to match the stable tag;
|
|
66
|
+
6. runs `twine check --strict`;
|
|
67
|
+
7. passes only the verified wheel and sdist to the publishing job as a short-lived Actions artifact.
|
|
68
|
+
|
|
69
|
+
The publishing job downloads that verified artifact and invokes `pypa/gh-action-pypi-publish@release/v1`. It does not build package distributions.
|
|
70
|
+
|
|
71
|
+
## API-token cleanup
|
|
72
|
+
|
|
73
|
+
The 0.1.0 first publication used a manually supplied PyPI API token because the project did not yet exist on PyPI when release automation was prepared. The Trusted Publisher was registered on 2026-08-30. Version 0.1.1 confirmed the OIDC path end-to-end, and version 0.1.2 independently reconfirmed exact-artifact Trusted Publishing plus post-publication hash and clean-install verification.
|
|
74
|
+
|
|
75
|
+
Any API token created solely for `gp3sequencespy` is therefore no longer required by the automated release path and can be revoked in PyPI account/project settings if it still exists.
|