hgvs-weaver-data 0.1.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.
Files changed (70) hide show
  1. hgvs_weaver_data-0.1.0/.claude/rules/design-docs.md +6 -0
  2. hgvs_weaver_data-0.1.0/.claude/rules/python.md +6 -0
  3. hgvs_weaver_data-0.1.0/.claude/rules/tests.md +9 -0
  4. hgvs_weaver_data-0.1.0/.claude/skills/writing-design-docs/SKILL.md +55 -0
  5. hgvs_weaver_data-0.1.0/.gitattributes +5 -0
  6. hgvs_weaver_data-0.1.0/.github/workflows/lint.yml +34 -0
  7. hgvs_weaver_data-0.1.0/.github/workflows/release.yml +61 -0
  8. hgvs_weaver_data-0.1.0/.github/workflows/schema-compat.yml +49 -0
  9. hgvs_weaver_data-0.1.0/.github/workflows/schema-freshness.yml +38 -0
  10. hgvs_weaver_data-0.1.0/.github/workflows/tests.yml +23 -0
  11. hgvs_weaver_data-0.1.0/.gitignore +11 -0
  12. hgvs_weaver_data-0.1.0/.pre-commit-config.yaml +58 -0
  13. hgvs_weaver_data-0.1.0/.yamlfmt +10 -0
  14. hgvs_weaver_data-0.1.0/CLAUDE.md +95 -0
  15. hgvs_weaver_data-0.1.0/GLOSSARY.md +52 -0
  16. hgvs_weaver_data-0.1.0/LICENSE +21 -0
  17. hgvs_weaver_data-0.1.0/PKG-INFO +62 -0
  18. hgvs_weaver_data-0.1.0/README.md +45 -0
  19. hgvs_weaver_data-0.1.0/buf.lock +6 -0
  20. hgvs_weaver_data-0.1.0/buf.yaml +23 -0
  21. hgvs_weaver_data-0.1.0/docs/PRODUCT.md +65 -0
  22. hgvs_weaver_data-0.1.0/docs/design/placements.md +202 -0
  23. hgvs_weaver_data-0.1.0/docs/design/retired-versions.md +142 -0
  24. hgvs_weaver_data-0.1.0/docs/style/design-docs.md +117 -0
  25. hgvs_weaver_data-0.1.0/docs/style/general.md +61 -0
  26. hgvs_weaver_data-0.1.0/docs/style/python.md +272 -0
  27. hgvs_weaver_data-0.1.0/docs/style/writing-tests.md +211 -0
  28. hgvs_weaver_data-0.1.0/proto/weaver_data_provider/v1/bundle.proto +195 -0
  29. hgvs_weaver_data-0.1.0/proto/weaver_data_provider/v1/genome.proto +53 -0
  30. hgvs_weaver_data-0.1.0/proto/weaver_data_provider/v1/index.proto +53 -0
  31. hgvs_weaver_data-0.1.0/proto/weaver_data_provider/v1/store.proto +92 -0
  32. hgvs_weaver_data-0.1.0/pyproject.toml +86 -0
  33. hgvs_weaver_data-0.1.0/scripts/fetch_refseq_status.py +218 -0
  34. hgvs_weaver_data-0.1.0/scripts/regen.py +40 -0
  35. hgvs_weaver_data-0.1.0/src/buf/__init__.py +0 -0
  36. hgvs_weaver_data-0.1.0/src/buf/validate/__init__.py +0 -0
  37. hgvs_weaver_data-0.1.0/src/buf/validate/validate_pb2.py +469 -0
  38. hgvs_weaver_data-0.1.0/src/buf/validate/validate_pb2.pyi +654 -0
  39. hgvs_weaver_data-0.1.0/src/weaver_data_provider/__init__.py +10 -0
  40. hgvs_weaver_data-0.1.0/src/weaver_data_provider/_files.py +105 -0
  41. hgvs_weaver_data-0.1.0/src/weaver_data_provider/build/__init__.py +44 -0
  42. hgvs_weaver_data-0.1.0/src/weaver_data_provider/build/cli.py +254 -0
  43. hgvs_weaver_data-0.1.0/src/weaver_data_provider/build/common.py +367 -0
  44. hgvs_weaver_data-0.1.0/src/weaver_data_provider/build/ensembl.py +536 -0
  45. hgvs_weaver_data-0.1.0/src/weaver_data_provider/build/genome.py +112 -0
  46. hgvs_weaver_data-0.1.0/src/weaver_data_provider/build/refseq.py +841 -0
  47. hgvs_weaver_data-0.1.0/src/weaver_data_provider/build/store.py +255 -0
  48. hgvs_weaver_data-0.1.0/src/weaver_data_provider/genome.py +165 -0
  49. hgvs_weaver_data-0.1.0/src/weaver_data_provider/keytable.py +97 -0
  50. hgvs_weaver_data-0.1.0/src/weaver_data_provider/provider.py +215 -0
  51. hgvs_weaver_data-0.1.0/src/weaver_data_provider/py.typed +0 -0
  52. hgvs_weaver_data-0.1.0/src/weaver_data_provider/refget.py +40 -0
  53. hgvs_weaver_data-0.1.0/src/weaver_data_provider/store.py +226 -0
  54. hgvs_weaver_data-0.1.0/src/weaver_data_provider/testing.py +194 -0
  55. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/__init__.py +0 -0
  56. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/bundle_pb2.py +109 -0
  57. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/bundle_pb2.pyi +204 -0
  58. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/genome_pb2.py +65 -0
  59. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/genome_pb2.pyi +42 -0
  60. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/index_pb2.py +50 -0
  61. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/index_pb2.pyi +37 -0
  62. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/store_pb2.py +84 -0
  63. hgvs_weaver_data-0.1.0/src/weaver_data_provider/v1/store_pb2.pyi +59 -0
  64. hgvs_weaver_data-0.1.0/tests/test_ensembl.py +688 -0
  65. hgvs_weaver_data-0.1.0/tests/test_genome.py +196 -0
  66. hgvs_weaver_data-0.1.0/tests/test_provider.py +202 -0
  67. hgvs_weaver_data-0.1.0/tests/test_refseq.py +1370 -0
  68. hgvs_weaver_data-0.1.0/tests/test_store.py +502 -0
  69. hgvs_weaver_data-0.1.0/tools/check_links.py +165 -0
  70. hgvs_weaver_data-0.1.0/uv.lock +1094 -0
@@ -0,0 +1,6 @@
1
+ ---
2
+ paths:
3
+ - "docs/design/**/*.md"
4
+ ---
5
+
6
+ Before writing or substantially rewriting a design doc, load the `writing-design-docs` skill.
@@ -0,0 +1,6 @@
1
+ ---
2
+ paths:
3
+ - "**/*.py"
4
+ ---
5
+
6
+ @../../docs/style/python.md
@@ -0,0 +1,9 @@
1
+ ---
2
+ paths:
3
+ - "**/tests/**"
4
+ - "**/test_*.py"
5
+ - "**/conftest.py"
6
+ - "src/weaver_data_provider/testing.py"
7
+ ---
8
+
9
+ @../../docs/style/writing-tests.md
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: writing-design-docs
3
+ description: "Write or substantially rewrite a design doc under `docs/design/`. The procedure: what to read before drafting, what stays in the doc versus what moves to the code, the shape to draft in, the self-read, and the checks. Use when authoring a new design doc, rewriting an existing one, splitting or folding one, or bringing a doc up to the guide."
4
+ ---
5
+
6
+ # Writing a design doc
7
+
8
+ The guidance is `docs/style/design-docs.md` — the reader, the style, where low-level detail goes, the default shape, the
9
+ policy. This is the procedure; it does not restate the guide.
10
+
11
+ ## Read first
12
+
13
+ - The guide.
14
+ - What the doc's reader has already read: `docs/PRODUCT.md`, `GLOSSARY.md`.
15
+ - The doc as it stands, where one exists, and the Overview of each doc that will appear under `Related`.
16
+ - The code and contract files the doc describes — the proto, the module entry points, the tests. "The code states it" is
17
+ verified there before a fact is left out, never assumed.
18
+
19
+ ## Separate what stays from what restates code
20
+
21
+ Stays: the decisions, the named interfaces and what each promises, the consequences, the alternatives and why each was
22
+ rejected, open questions.
23
+
24
+ Goes: per-field paraphrase of a proto or schema, env-var names, paths beyond an entry point, function, class and test
25
+ names, error strings, constants.
26
+
27
+ For each code-owned fact the doc does not carry, note where it lives — the comment on the proto field, the docstring,
28
+ the test — or that it has no home yet because that code does not exist on this branch. Keep the list; it is part of the
29
+ report. No such fact goes into an inline comment beside the implementation (`docs/style/general.md`, Comments).
30
+
31
+ ## Draft
32
+
33
+ The guide's default shape, deviating where the design reads better another way. A doc covering a surface, a flow, or
34
+ several interfaces uses the concrete forms the guide names: a mockup of the surface, a request diagram, a plain
35
+ statement of what is stored where, one subsection per interface in one consistent shape.
36
+
37
+ ## Re-read as the reader
38
+
39
+ Read the draft as the maintainer the guide describes — has read `PRODUCT.md` and `GLOSSARY.md`, knows nothing about the
40
+ area, one read on GitHub. Can they state each decision and the reason for it afterwards? Where not, fix the passage, not
41
+ the reader.
42
+
43
+ ## Checks
44
+
45
+ - `python3 tools/check_links.py` from the repo root — it scans all tracked Markdown, so read only the lines naming the
46
+ doc.
47
+ - `pre-commit run mdformat --files <doc>`.
48
+ - After the push, check a mermaid block in the branch's file view on GitHub; the PR diff will not render it, so a
49
+ reviewer opens the file.
50
+ - The header line carries `**Related:**`.
51
+
52
+ ## Report
53
+
54
+ Where each code-owned fact lives, calling out the ones with no home yet so the author can push them onto the code's
55
+ documentation surface when it lands. Any question the writing raised for the author.
@@ -0,0 +1,5 @@
1
+ # Generated protobuf stubs: collapse in GitHub diffs and drop from language stats.
2
+ # Collapse only — GitHub still counts these lines in a PR's +/- total, as with any
3
+ # lockfile; to inspect one, expand it in the diff.
4
+ **/*_pb2.py linguist-generated=true
5
+ **/*_pb2.pyi linguist-generated=true
@@ -0,0 +1,34 @@
1
+ name: lint
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, ready_for_review, synchronize]
6
+ push:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ pre-commit:
11
+ # Runs every hook in .pre-commit-config.yaml — the whole static-check gate. Skips draft PRs.
12
+ if: github.event_name != 'pull_request' || !github.event.pull_request.draft
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: read
16
+ steps:
17
+ - uses: actions/checkout@v7
18
+ - uses: astral-sh/setup-uv@v10.2.0
19
+ with:
20
+ enable-cache: true
21
+ # buf on PATH for the buf-lint hook.
22
+ - uses: bufbuild/buf-setup-action@v1.50.0
23
+ with:
24
+ version: "1.73.0"
25
+ # No default token: the release lookup that resolves the download URL would go out
26
+ # anonymous, against a per-IP rate limit shared across the hosted runner pool.
27
+ github_token: ${{ github.token }}
28
+ # Pre-sync the env so the pyright hook's `uv run` is a no-op.
29
+ - run: uv sync --locked --python 3.13
30
+ - uses: actions/cache@v6
31
+ with:
32
+ path: ~/.cache/pre-commit
33
+ key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
34
+ - run: uv run pre-commit run --all-files --show-diff-on-failure
@@ -0,0 +1,61 @@
1
+ name: release
2
+
3
+ # A `v*` tag builds, tests, publishes to PyPI through the trusted publisher registered for this
4
+ # workflow (environment `pypi`), and creates the GitHub release with the built distributions.
5
+ on:
6
+ push:
7
+ tags: ["v*"]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ permissions:
13
+ contents: read
14
+ steps:
15
+ - uses: actions/checkout@v7
16
+ - uses: astral-sh/setup-uv@v10.2.0
17
+ with:
18
+ enable-cache: true
19
+ # The tag is the release's name; the wheel's version comes from pyproject.toml. They must agree,
20
+ # or PyPI shows one version and the repo another.
21
+ - name: Check the tag matches the package version
22
+ run: |
23
+ set -euo pipefail
24
+ version="$(uv version --short)"
25
+ if [ "v${version}" != "${GITHUB_REF_NAME}" ]; then
26
+ echo "::error::tag ${GITHUB_REF_NAME} does not match pyproject version ${version}"
27
+ exit 1
28
+ fi
29
+ - run: uv sync --locked --python 3.13
30
+ - run: uv run pytest
31
+ - run: uv build
32
+ - uses: actions/upload-artifact@v7
33
+ with:
34
+ name: dist
35
+ path: dist/
36
+ if-no-files-found: error
37
+
38
+ publish:
39
+ needs: build
40
+ runs-on: ubuntu-latest
41
+ environment:
42
+ name: pypi
43
+ url: https://pypi.org/project/hgvs-weaver-data/${{ github.ref_name }}
44
+ permissions:
45
+ # OIDC token for PyPI trusted publishing; contents for the GitHub release.
46
+ id-token: write
47
+ contents: write
48
+ steps:
49
+ - uses: actions/download-artifact@v8
50
+ with:
51
+ name: dist
52
+ path: dist/
53
+ - uses: pypa/gh-action-pypi-publish@v1.14.2
54
+ - name: Create the GitHub release
55
+ env:
56
+ GH_TOKEN: ${{ github.token }}
57
+ run: |-
58
+ gh release create "${GITHUB_REF_NAME}" dist/* \
59
+ --repo "${GITHUB_REPOSITORY}" \
60
+ --title "hgvs-weaver-data ${GITHUB_REF_NAME#v}" \
61
+ --generate-notes
@@ -0,0 +1,49 @@
1
+ name: schema-compat
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, ready_for_review, synchronize]
6
+ push:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ backward-compatible:
11
+ # `buf breaking` under the FILE rule set (buf.yaml): stores and genomes already written sit in
12
+ # other projects' buckets, so a renumber or type change of a committed field fails here.
13
+ # Skips draft PRs.
14
+ if: github.event_name != 'pull_request' || !github.event.pull_request.draft
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: read
18
+ steps:
19
+ # Full history: the baseline is a commit, not the checkout.
20
+ - uses: actions/checkout@v7
21
+ with:
22
+ fetch-depth: 0
23
+ - uses: bufbuild/buf-setup-action@v1.50.0
24
+ with:
25
+ version: "1.73.0"
26
+ # No default token: the release lookup that resolves the download URL would go out
27
+ # anonymous, against a per-IP rate limit shared across the hosted runner pool.
28
+ github_token: ${{ github.token }}
29
+ # Baseline = what main held before this change. For a PR that is the base branch tip; on a push
30
+ # it is the commit the push started from, so every commit a multi-commit push brings is compared.
31
+ # A push that creates the branch has no before, and falls back to the previous commit; a root
32
+ # commit has no baseline and is skipped.
33
+ - name: Resolve baseline ref
34
+ id: baseline
35
+ env:
36
+ BEFORE: ${{ github.event.before }}
37
+ run: |
38
+ set -euo pipefail
39
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
40
+ echo "ref=origin/${{ github.base_ref }}" >> "$GITHUB_OUTPUT"
41
+ elif [ -n "${BEFORE:-}" ] && [ "${BEFORE}" != "0000000000000000000000000000000000000000" ]; then
42
+ echo "ref=${BEFORE}" >> "$GITHUB_OUTPUT"
43
+ elif git rev-parse --verify -q HEAD^ >/dev/null; then
44
+ echo "ref=HEAD^" >> "$GITHUB_OUTPUT"
45
+ else
46
+ echo "ref=" >> "$GITHUB_OUTPUT"
47
+ fi
48
+ - if: steps.baseline.outputs.ref != ''
49
+ run: buf breaking --against ".git#ref=${{ steps.baseline.outputs.ref }}"
@@ -0,0 +1,38 @@
1
+ name: schema-freshness
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, ready_for_review, synchronize]
6
+ push:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ regen-is-fresh:
11
+ # Skips draft PRs.
12
+ if: github.event_name != 'pull_request' || !github.event.pull_request.draft
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: read
16
+ steps:
17
+ - uses: actions/checkout@v7
18
+ # buf exports the protos + deps for protoc. No remote plugins — codegen is grpcio-tools' protoc.
19
+ - uses: bufbuild/buf-setup-action@v1.50.0
20
+ with:
21
+ version: "1.73.0"
22
+ # No default token: the release lookup that resolves the download URL would go out
23
+ # anonymous, against a per-IP rate limit shared across the hosted runner pool.
24
+ github_token: ${{ github.token }}
25
+ - uses: astral-sh/setup-uv@v10.2.0
26
+ with:
27
+ enable-cache: true
28
+ - run: uv run --locked --group codegen python scripts/regen.py
29
+ # The committed stubs must equal what regen just produced. `git add -A` stages edits, new
30
+ # files, and deletions; a non-empty staged diff means a .proto (or a tool) changed without
31
+ # regenerating.
32
+ - name: Fail if committed stubs are stale
33
+ run: |-
34
+ git add -A
35
+ if ! git diff --cached --exit-code; then
36
+ echo "::error::Generated stubs are stale. Run 'uv run --group codegen python scripts/regen.py' and commit the result."
37
+ exit 1
38
+ fi
@@ -0,0 +1,23 @@
1
+ name: tests
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, ready_for_review, synchronize]
6
+ push:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ pytest:
11
+ # Skips draft PRs.
12
+ if: github.event_name != 'pull_request' || !github.event.pull_request.draft
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: read
16
+ steps:
17
+ - uses: actions/checkout@v7
18
+ - uses: astral-sh/setup-uv@v10.2.0
19
+ with:
20
+ enable-cache: true
21
+ - run: uv sync --locked --python 3.13
22
+ # No path arg: collect the testpaths configured in pyproject.toml.
23
+ - run: uv run pytest
@@ -0,0 +1,11 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ # Anchored: an unanchored `build/` also matches the builder package, src/weaver_data_provider/build.
7
+ /dist/
8
+ /build/
9
+ *.egg-info/
10
+ .claude/worktrees/
11
+ .claude/settings.local.json
@@ -0,0 +1,58 @@
1
+ # `pre-commit run --all-files` is the lint gate, locally and in CI. A hook added here is gated with no
2
+ # separate workflow edit. pytest stays a separate job (too slow for the per-commit path).
3
+ default_language_version:
4
+ python: python3.13
5
+ repos:
6
+ - repo: https://github.com/pre-commit/pre-commit-hooks
7
+ rev: v6.0.0
8
+ hooks:
9
+ - id: check-yaml
10
+ # Generated stubs are committed verbatim from protoc; a hygiene rewrite would drift them from
11
+ # the generator and break the freshness gate.
12
+ - id: end-of-file-fixer
13
+ exclude: '^src/(weaver_data_provider/v1|buf)/'
14
+ - id: trailing-whitespace
15
+ exclude: '^src/(weaver_data_provider/v1|buf)/'
16
+ - id: check-case-conflict
17
+ - id: check-merge-conflict
18
+ - id: detect-private-key
19
+ - id: debug-statements
20
+ - id: check-added-large-files
21
+ args: [--maxkb=1024]
22
+ - repo: https://github.com/astral-sh/ruff-pre-commit
23
+ rev: v0.15.12
24
+ hooks:
25
+ - id: ruff
26
+ - id: ruff-format
27
+ - repo: local
28
+ hooks:
29
+ # pyright needs the project deps to resolve imports, so it runs in the lint env via `uv run`.
30
+ # Whole-project (pass_filenames: false); fires on any staged .py.
31
+ - id: pyright
32
+ name: pyright
33
+ entry: uv run --group lint pyright
34
+ language: system
35
+ files: \.py$
36
+ pass_filenames: false
37
+ # buf lint: the hand-authored protos' structural and protovalidate discipline (buf.yaml).
38
+ # Whole-module; fires on any staged .proto. Needs buf on PATH.
39
+ - id: buf-lint
40
+ name: buf lint
41
+ entry: buf lint
42
+ language: system
43
+ files: \.proto$
44
+ pass_filenames: false
45
+ # Markdown formatter. CommonMark-strict, so intraword `_` (snake_case) stays literal and fenced
46
+ # code is untouched. gfm = tables/task-lists/autolinks; frontmatter = YAML headers. Wrap at 120.
47
+ - repo: https://github.com/hukkin/mdformat
48
+ rev: 1.0.0
49
+ hooks:
50
+ - id: mdformat
51
+ args: ["--wrap", "120"]
52
+ additional_dependencies:
53
+ - mdformat-gfm==1.0.0
54
+ - mdformat-frontmatter==2.1.2
55
+ - repo: https://github.com/google/yamlfmt
56
+ rev: v0.21.0
57
+ hooks:
58
+ - id: yamlfmt
@@ -0,0 +1,10 @@
1
+ # YAML formatter config; the YAML analogue of ruff-format / biome.
2
+ # retain_line_breaks_single: yamlfmt can't selectively strip blank lines
3
+ # between block-sequence items, so the no-blank-line-between-steps layout in
4
+ # .github/workflows is kept by hand — this setting only stops yamlfmt from
5
+ # reintroducing or multiplying blank lines elsewhere.
6
+ formatter:
7
+ type: basic
8
+ retain_line_breaks_single: true
9
+ trim_trailing_whitespace: true
10
+ eof_newline: true
@@ -0,0 +1,95 @@
1
+ # hgvs-weaver-data development notes
2
+
3
+ ## Product
4
+
5
+ See [`docs/PRODUCT.md`](docs/PRODUCT.md) for the product north star — what the package is, the load-bearing principles
6
+ (the publisher's placement, never a derived one; the files at rest are a contract; an answer or an error, never a
7
+ guess), and what is out of scope. Read it before proposing designs or plans. Shared terminology lives in
8
+ [`GLOSSARY.md`](GLOSSARY.md).
9
+
10
+ ## Working norms
11
+
12
+ Operating directives for Claude (and any agent) in this repo; they counteract default model dispositions.
13
+
14
+ - **Resist the minimal-diff reflex.** Don't reach for the smallest change that hides the symptom (special-casing,
15
+ papering over root causes). Aim for the correct fix at the right complexity level — not the smallest, not gold-plated.
16
+ - **Fail loudly and early.** Raise on a missing expected input or precondition; never fall back to a default/placeholder
17
+ to limp along. A placeholder is an explicit caller input, never a code default.
18
+ - **Never instruct around a defect — fix the defect.** Don't write prose telling readers to work around broken code —
19
+ "pass it as a string, the converter loses precision". Prose is untested, and callers who didn't read it stay broken.
20
+ - **Push back; don't just comply.** When a design, name, or approach seems worse — including a shortcut you're asked to
21
+ take — say so with reasoning, unprompted. The author owns the final call.
22
+ - **Offer better alternatives with trade-offs.** When a materially better approach than the proposed one exists, present
23
+ it and the trade-offs — don't just execute the ask.
24
+ - **Investigate before producing.** Read the code and verify constraints first. Don't treat a training-pattern
25
+ convention as load-bearing unchecked; don't speculate about what you can read.
26
+ - **Explain non-obvious changes first.** For a change whose rationale isn't self-evident, give the why before showing or
27
+ applying the diff.
28
+ - **Ask when unsure** rather than assume intent.
29
+ - **No intensifiers or emphasis filler.** Drop words and phrases that add emphasis but no information — "that's the
30
+ key", "crucially", "importantly", "the key insight", "it's worth noting". State the point plainly. Applies to all
31
+ prose: chat replies, PR/review comments, commit messages, and docs.
32
+
33
+ ## Code style
34
+
35
+ @docs/style/general.md
36
+
37
+ Tests — what one asserts, what it may depend on, what its data may contain — follow
38
+ [`docs/style/writing-tests.md`](docs/style/writing-tests.md); it loads when a test file is touched.
39
+
40
+ ## Schema
41
+
42
+ The protos under `proto/` are the source of truth for the files at rest; the committed Python stubs are generated. After
43
+ editing a proto: `buf lint`, `buf breaking --against .git#branch=main`, then
44
+ `uv run --group codegen python scripts/regen.py` and commit the stubs with the proto. Evolution is additive only — CI's
45
+ `schema-compat` job fails a renumber or type change. A change a reader cannot ignore bumps `FORMAT_VERSION`, so an old
46
+ reader refuses the new files rather than misreading them.
47
+
48
+ ## Dependency direction
49
+
50
+ At runtime this package depends on hgvs-weaver and never the reverse ([`docs/PRODUCT.md`](docs/PRODUCT.md)). Don't
51
+ propose a change that makes weaver's runtime or CLI import this package; its test suite may.
52
+
53
+ ## Docs
54
+
55
+ Two audiences, two registers:
56
+
57
+ - **Instruction files** are prompts and rules — `CLAUDE.md`, `.claude/rules/`, `.claude/skills/`: model-only, only what
58
+ changes behavior, no maintainer notes, no harness mechanics (which rules load when, where files live). A token there
59
+ is paid on every run that loads it; human-facing explanation belongs in `docs/` or code.
60
+ - **Everything under `docs/`** is written for a human first — a maintainer who has read
61
+ [`docs/PRODUCT.md`](docs/PRODUCT.md) and [`GLOSSARY.md`](GLOSSARY.md) but not this area, and has to get the take-aways
62
+ from one read on GitHub. Explain with the clarity and style of Martin Kleppmann — motivation before mechanism,
63
+ specifics out of the argument's way. Detail that restates code — field lists, paths, env vars, test names — stays in
64
+ the code and is linked, never transcribed. A model reads what a human reads. Design docs are the durable design
65
+ record: one living doc per area under `docs/design/`, rewritten in place; no ADRs — rationale lives in the doc,
66
+ chronology in git. The guide is [`docs/style/design-docs.md`](docs/style/design-docs.md); to write or rewrite one,
67
+ load the `writing-design-docs` skill.
68
+
69
+ ## Committing
70
+
71
+ - **Stage explicit paths**, not `git add -A` / `.`; explicit staging avoids sweeping in an untracked file.
72
+ - **Pre-commit runs lint/format/hygiene** (`.pre-commit-config.yaml`); CI runs the same hooks plus pytest. Ensure hooks
73
+ are installed (`pre-commit install`) — if not, install or ask the author; never bypass with `--no-verify`.
74
+ - **Correct a pushed branch with a new commit on top**, not amend + force-push. PRs squash-merge, so `main` history
75
+ stays linear regardless and intermediate fixups vanish on merge. Reserve force-push for rebasing a branch onto `main`.
76
+
77
+ ## Worktrees
78
+
79
+ Worktrees go in `.claude/worktrees/` (gitignored), never `../` siblings.
80
+
81
+ - **New branch** → the Claude Code worktree command.
82
+ - **Existing branch** → `git worktree add .claude/worktrees/<name> <branch>` (the command only cuts fresh branches).
83
+
84
+ ## CI and review
85
+
86
+ - **Adversarially review before opening a PR.** For any change with non-trivial code or logic, run adversarial review
87
+ passes in subagents with fresh context — the reviewer sees only the diff, not the authoring conversation — and fix the
88
+ findings autonomously; repeat until a pass surfaces only diminishing findings, then open the PR. Exempt: trivial
89
+ changes, doc-only changes, resource/asset changes.
90
+ - **A PR description is written for the human reviewer**: what the change is and why, the take-aways, and where to look
91
+ — the altitude of a design doc's Overview, shorter. The diff carries the detail; don't narrate it. Same style:
92
+ [`docs/style/design-docs.md` § Style](docs/style/design-docs.md#style).
93
+ - **Pin third-party GitHub Actions to the latest stable release**: the moving major tag (`@v7`) where the action
94
+ publishes one, else the exact latest version (`@v10.2.0`). Verify against the action's releases when adding or bumping
95
+ one.
@@ -0,0 +1,52 @@
1
+ # Glossary
2
+
3
+ Shared terms across hgvs-weaver-data docs and code.
4
+
5
+ ## Reference data
6
+
7
+ - **Assembly** — one version of the reference genome, GRCh38 or GRCh37. Coordinates mean nothing without the assembly
8
+ they are on, so every alignment and every store names its assembly.
9
+ - **Annotation release** — one publication of a publisher's gene and transcript models against an assembly, named by the
10
+ publisher (`RS_2024_08` for RefSeq).
11
+ - **Transcript record** — the publisher's own sequence of a transcript (an `NM_` or `NR_` accession with its version).
12
+ It usually matches the genome spliced at the transcript's exons, but not always.
13
+ - **Alignment** (or **placement**) — where a transcript sits on one sequence of an assembly: its exons, strand, and the
14
+ per-exon CIGAR that says how the record and the genome differ. Published by NCBI; never derived here. A transcript can
15
+ have several — on X and on Y, on a chromosome and on a patch, or on each alternate locus that carries its gene.
16
+ - **Alternate locus** — a scaffold holding another haplotype of a region too variable for one sequence (the MHC, the KIR
17
+ cluster). A gene the primary assembly's haplotype lacks is placed only on alternate loci. Alternate loci are `NT_`
18
+ accessions, as are the unlocalized and unplaced scaffolds of the primary assembly.
19
+ - **Patch** — an `NW_` scaffold released between assembly versions: a fix patch corrects the primary assembly (and is
20
+ folded into the next major release), a novel patch adds alternate sequence.
21
+ - **MANE** — the NCBI/EMBL-EBI project that picks one representative transcript per protein-coding gene (MANE Select)
22
+ and matches it across RefSeq and Ensembl. It ranks transcripts; it does not place them.
23
+ - **HGNC** — the committee that assigns human gene symbols; the source of each gene's current, previous and alias
24
+ symbols.
25
+ - **refget digest** — a sequence's identity computed from its residues (sha512t24u, written `SQ.…`), so two copies of
26
+ the same sequence share an identifier whatever they are called.
27
+
28
+ ## Project
29
+
30
+ - **Gene bundle** (or **bundle**) — the unit of storage: one gene with every transcript, protein, alignment and sequence
31
+ that belongs to it (`GeneBundle` in `proto/`).
32
+ - **Shard** — one annotation release's bundles in one bagz file, immutable once written and named for its contents.
33
+ - **Store** — an index over an ordered list of shards: the key tables (symbol, accession, protein, digest), the interval
34
+ tables (bundles by genome position), and the **manifest** that names the shards, written last.
35
+ - **Genome** — a derived copy of an assembly: the **blocks file**, every sequence cut into fixed-size compressed blocks,
36
+ and the **catalogue** of names, lengths and refget digests, written last.
37
+ - **Format version** — the number every manifest and catalogue carries; a reader refuses one it does not know.
38
+ - **Provider** — the object weaver reads through: weaver's `DataProvider` over one assembly's store and genome.
39
+
40
+ ## Testing
41
+
42
+ - **Test double** — anything standing in for a production dependency in a test. The kinds below differ in fidelity and
43
+ in what a test can do with them
44
+ ([`docs/style/writing-tests.md`](docs/style/writing-tests.md#test-doubles-in-order-of-fidelity)).
45
+ - **Fake** — a working, lightweight implementation of an interface, unsuitable for production and held to the real
46
+ implementation's contract.
47
+ - **Stub** — returns canned values to put the code under test in a state; makes no claim about being called.
48
+ - **Mock** — carries expectations about how it is called and fails the test when they are not met; the only double a
49
+ test verifies interactions on.
50
+ - **Change detector** — a test that pins the code's current shape rather than an invariant, so it fails on every
51
+ legitimate change and catches no defect.
52
+ - **Flaky test** — one that passes and fails on the same code; a defect to root-cause, never a reason to rerun.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Centre for Population Genomics
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.5
2
+ Name: hgvs-weaver-data
3
+ Version: 0.1.0
4
+ Summary: Reference data for the hgvs-weaver HGVS engine: a builder that cuts RefSeq and Ensembl releases into gene bundles, and the DataProvider that reads them.
5
+ Author-email: Tobias Sargeant <toby.sargeant@populationgenomics.org.au>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.12
9
+ Requires-Dist: bagz[gcs]>=0.3.8
10
+ Requires-Dist: google-cloud-storage>=2.18
11
+ Requires-Dist: google-crc32c>=1.5
12
+ Requires-Dist: hgvs-weaver>=0.7
13
+ Requires-Dist: protobuf<7,>=6.33.5
14
+ Requires-Dist: protovalidate>=1.2
15
+ Requires-Dist: pysam>=0.23
16
+ Description-Content-Type: text/markdown
17
+
18
+ # hgvs-weaver-data
19
+
20
+ Reference data for [hgvs-weaver](https://github.com/populationgenomics/hgvs-weaver): a builder that turns a publisher's
21
+ release into a local store, and the `DataProvider` that feeds weaver from it.
22
+
23
+ An HGVS engine is only as correct as what it is told about each transcript. A RefSeq transcript's sequence is not always
24
+ the genome's — about one record in forty differs — and where they differ by an insertion or deletion, where the
25
+ difference sits is a choice. NCBI publishes its choice: the alignment of every RefSeq transcript to the assembly. The
26
+ builder takes that alignment exon by exon rather than deriving one, so the positions weaver computes are the ones
27
+ ClinVar's names and VariantValidator's projections follow.
28
+
29
+ Every placement NCBI publishes is kept — on a chromosome, an alternate locus or a patch — so a gene the primary assembly
30
+ lacks is served where it is. An Ensembl transcript is placed at its exons, after a check that its record is the genome
31
+ spliced there. [`docs/design/placements.md`](docs/design/placements.md) has the reasons. A retired RefSeq version — the
32
+ one an older variant name cites — is served from NCBI's historical set, stacked under the current release
33
+ ([`docs/design/retired-versions.md`](docs/design/retired-versions.md)).
34
+
35
+ A store is one record per gene — every transcript, its protein, its alignments and the sequences they cite — in
36
+ [bagz](https://github.com/google-deepmind/bagz) files with sorted key and interval tables that are read into memory at
37
+ open. A lookup is a search over bytes in memory and one ranged read, from local disk or `gs://`.
38
+
39
+ ```sh
40
+ weaver-data-build refseq ... # one RefSeq release's bundles, as a shard
41
+ weaver-data-build historical ... # NCBI's historical set of RefSeq versions, each with its Entrez status
42
+ # (scripts/fetch_refseq_status.py), as a shard to stack under a release's
43
+ weaver-data-build ensembl ... # one Ensembl release's, placed at its exons and checked against the genome
44
+ weaver-data-build index ... # the index and manifest over an ordered list of shards
45
+ weaver-data-build genome ... # the assembly, cut into compressed blocks
46
+ ```
47
+
48
+ The at-rest format is defined by the protos under `proto/`, and `buf breaking` gates every change: stores sit in other
49
+ projects' buckets, so the format only grows.
50
+
51
+ ## Installing
52
+
53
+ `pip install hgvs-weaver-data`; the module is `weaver_data_provider`.
54
+
55
+ ## Platforms
56
+
57
+ bagz publishes wheels for Linux x86_64 and macOS arm64; anywhere else, installing this package builds bagz from source.
58
+
59
+ ## Development
60
+
61
+ `uv sync`, then `uv run pytest`. The Python stubs under `src/` are generated from `proto/` by
62
+ `uv run python scripts/regen.py` and committed.