Skip to content

feat: grant DAKP sparse qualifier stack on pinned association classes - #188

Merged
SkyeAv merged 2 commits into
mainfrom
add-qualifier-overrides
Sep 15, 2026
Merged

SkyeAv merged 2 commits into
mainfrom
add-qualifier-overrides

Conversation

@SkyeAv

@SkyeAv SkyeAv commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Grants anatomical_context_qualifier, sex_qualifier, population_context_qualifier, frequency_qualifier, and temporal_context_qualifier to EntityToDiseaseAssociation / EntityToPhenotypicFeatureAssociation via CLASS_FIELD_OVERRIDES, so DAKP assertion rows carrying the sparse qualifier stack keep those qualifiers on the edge instead of losing them in prune_to_class.

Qualifier grants

  • New grants: adds the five satisfiable DAKP stack qualifiers to both pinned classes in src/tablassert/biolink.py, alongside the existing disease_context_qualifier / regulatory_approvals grants.
  • Deliberate exclusions: species_context_qualifier stays ungranted (in DISABLED_EDGE_FIELDS, never emittable); temporal_interval_qualifier and severity_qualifier stay ungranted (in UNSATISFIABLE_EDGE_FIELDS, attached to no class, so a grant could never validate).
  • Validation: no new extra_forbidden surface; _validation_record already strips granted fields from its in-memory copy, and the existing tripwire test fails if a future biolink-model release attaches a granted slot.

Agent guidance

  • CURIE list: src/tablassert/agent.py now names population_context_qualifier, frequency_qualifier, and temporal_context_qualifier alongside the existing three in the CURIE-ranged qualifier sentence.

Docs

  • docs/configuration/table.md: category_override row and allow-list section now document the sparse-stack grants and the three deliberate exclusions.
  • CHANGELOG.md: Unreleased entry describing the grants and exclusions.

Testing

  • uv run pytest tests/test_biolink.py tests/test_lib.py::test_prune_to_class_keeps_class_field_override_grants tests/test_lib.py::test_prune_to_class_keeps_override_only_slots tests/test_models.py tests/test_rig.py -p no:cacheprovider -o addopts="" -q -> 180 passed
  • uv run pytest tests/test_docs_source_of_truth.py tests/test_agent_compact.py tests/test_agent_docs.py -p no:cacheprovider -o addopts="" -q -> 221 passed
  • uv run pytest tests/ -p no:cacheprovider -o addopts="" -q --ignore=tests/test_qc.py -> 1607 passed, 52 skipped, 2 failed; both failures are pre-existing environment gaps (missing [qc] extra packages; a log-capture assertion), unrelated to this change.
  • uv run ruff check -> clean; uv run ruff format --check -> clean after one applied reformat.

Grants anatomical_context_qualifier, sex_qualifier,
population_context_qualifier, frequency_qualifier, and
temporal_context_qualifier to EntityToDiseaseAssociation /
EntityToPhenotypicFeatureAssociation via CLASS_FIELD_OVERRIDES, so DAKP
assertion rows carrying the sparse qualifier stack keep those
qualifiers on the edge instead of losing them in prune_to_class.
species_context_qualifier stays ungranted (disabled);
temporal_interval_qualifier and severity_qualifier stay ungranted
(unsatisfiable).
@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 039fd7f8-b97a-4c6a-a351-e48f11b76f50


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@SkyeAv SkyeAv changed the title add qualifier overrides feat: grant DAKP sparse qualifier stack on pinned association classes Sep 15, 2026
Compresses the CURIE-ranged qualifier sentence so the expanded slot
list fits the budget the agent-speed guard enforces.
@SkyeAv
SkyeAv merged commit 00c6ffa into main Sep 15, 2026
5 checks passed
SkyeAv added a commit that referenced this pull request Sep 15, 2026
Cut 19.0.0 and bump the package version in pyproject.toml, CITATION.cff,
and uv.lock.

Major: five breaking changes ship. The `tablassert` console command now
requires the optional `[cli]` extra, since `cyclopts` and `rich` left the
base install (#187). Level-one normalization redefines fullmap keys as
cleaned Unicode-lowercase, Porter2-normalized, byte-ordered token sets and
moves the database to schema v6, so every schema-v5 fullmap is rejected and
must be rebuilt (#171, #172, #174, #175, #176). `build-fullmap --aria2c`
is gone -- aria2c is used automatically whenever the `[aria2]` extra is
installed (#178) -- and `--taxon-allowlist` is gone because the built-in
top-100 experimental-taxon allowlist now applies to every build, guarding
both reuse paths by `META.taxon_allowlist` identity (#153). Logging now
requires the `[log]` extra and is fully disabled without it (#152).

Features: `tablassert.net` is a new stdlib-only transient/permanent
classification and retry seam shared by the agent and the BABEL downloader
(#163, #164), with one bounded jittered retry layer across the inner agent,
reflexion, and judge (#167) and machine-readable `error_code` values on
skipped checkpoint records (#166). `build-kg` gained an automatic ephemeral
shared-prefix TCode cache keyed by content-addressed XXH64 op digests
(#155-#159, #161). The `--distill` corpus became schema-uniform v2 with a
sibling `outcomes.ndjson`, a deterministic `RewardConfig`-tunable reward,
and the new zero-dependency `tablassert distill-weigh` command (#180-#183).
`CLASS_FIELD_OVERRIDES` grants the DAKP sparse qualifier stack on the pinned
association classes (#188).

Fixes: `distill-export` partitions its corpus by content and unions the
schema across record files, so a mixed v1/v2 directory no longer CastErrors
or silently stringifies a column (#184); BABEL retry warnings survive the
loguru sink; PMC downloads are idempotent, atomic, and bounded-parallel
(#165); reflexion and judge prompts are hard-bounded (#168).

Changelog:
- versioned the Unreleased section as 19.0.0 - 2026-09-15
- merged three duplicate `### Added` blocks into one
- moved the two `BREAKING:` entries from `### Changed` into
  `### Breaking Changes` and added a `**Migration:**` note to all five
- added PR links to all 17 entries, which carried none
- added the missing entries: the distill v2 corpus/reward/distill-weigh
  stack (#180-#183), the distill-export schema-drift fix (#184), the
  TCode run-cache detail (#155-#161), and the README badge removal (#154)

Docs: none needed here. Every shipped doc change landed with its own PR,
and the docs source-of-truth gate passes against the bumped tree.

Testing:
- make check -> exit 0
- uv run ruff check . -> All checks passed!
- uv run pyright -> 0 errors, 0 warnings, 0 informations
- uv run pytest -> 1622 passed, 52 skipped
- cargo test --manifest-path rust/Cargo.toml -> 156 passed, 0 failed
- cargo clippy --all-targets -- -D warnings -> clean
- uv lock --check -> resolved 169 packages, lock current
- uv run mkdocs build --strict -> exit 0
- docs SSOT + CLI coverage after the changelog edit -> 204 passed
SkyeAv added a commit to glusman-team/dakp that referenced this pull request Sep 15, 2026
Take the release that grants DAKP's sparse qualifier stack (SkyeAv/Tablassert#188)
and absorb the three breaking changes that ride with it.

- `pyproject.toml`: `tablassert[cli,log,qc]>=19.0.0,<20`. 19.0 moved the `tablassert`
  console script behind the optional `[cli]` extra (its launcher preflights the extra
  and exits before importing the app) and made logging a silent no-op without `[log]`.
  `TablassertRunner` shells out to that console script and reads its stdout/stderr, so
  both extras are load-bearing here, not optional niceties.
- Fullmaps must now be `tablassert.fullmap.v6`. 19.0 rebased level-one normalization
  onto stemmed, deduped, byte-sorted tokens, which changed the RECORDS key SPACE: a v5
  database is not an older layout of the same data, its keys can never be hit by a
  normalized query, and v1-v5 are rejected on read. The runner's missing-fullmap error
  and the `FULLMAP_DEFAULT` docs now say v6 and explain why it is not a relayout.
- No emitted-config change lands here; the qualifier wiring the grant enables is the
  next commit.

Verification: `uv run pytest` -> 1131 passed (coverage 99.84%, misses are the
pre-existing aria2c/loopback network-gated lines, unchanged by this commit);
`ruff check` + `ruff format --check` clean; `uv run tablassert --help` exits 0 against
the installed 19.0.0, and `CLASS_FIELD_OVERRIDES` reports all five qualifier grants.
SkyeAv added a commit to glusman-team/dakp that referenced this pull request Sep 15, 2026
Take the release that grants DAKP's sparse qualifier stack (SkyeAv/Tablassert#188)
and absorb the three breaking changes that ride with it.

- `pyproject.toml`: `tablassert[cli,log,qc]>=19.0.0,<20`. 19.0 moved the `tablassert`
  console script behind the optional `[cli]` extra (its launcher preflights the extra
  and exits before importing the app) and made logging a silent no-op without `[log]`.
  `TablassertRunner` shells out to that console script and reads its stdout/stderr, so
  both extras are load-bearing here, not optional niceties.
- Fullmaps must now be `tablassert.fullmap.v6`. 19.0 rebased level-one normalization
  onto stemmed, deduped, byte-sorted tokens, which changed the RECORDS key SPACE: a v5
  database is not an older layout of the same data, its keys can never be hit by a
  normalized query, and v1-v5 are rejected on read. The runner's missing-fullmap error
  and the `FULLMAP_DEFAULT` docs now say v6 and explain why it is not a relayout.
- No emitted-config change lands here; the qualifier wiring the grant enables is the
  next commit.

Verification: `uv run pytest` -> 1131 passed (coverage 99.84%, misses are the
pre-existing aria2c/loopback network-gated lines, unchanged by this commit);
`ruff check` + `ruff format --check` clean; `uv run tablassert --help` exits 0 against
the installed 19.0.0, and `CLASS_FIELD_OVERRIDES` reports all five qualifier grants.
SkyeAv added a commit to glusman-team/dakp that referenced this pull request Sep 15, 2026
…nfigs

Tablassert 19.0.0's CLASS_FIELD_OVERRIDES grant (SkyeAv/Tablassert#188) keeps
DAKP's five sparse qualifier slots on the pinned association classes through
prune_to_class — the upstream unblock the qualifier columns were waiting for.
Wire them now that the grant exists.

- `_TABLE_QUALIFIERS`: approved-treats and contraindication tables declare
  `anatomical_context_qualifier` / `sex_qualifier` / `population_context_qualifier`
  / `frequency_qualifier` / `temporal_context_qualifier`, each backed by the
  assertion column its sentence-hosted attachment (contexts.attach_qualifiers)
  already populates. The FAERS table declares none: its writer populates no
  qualifier column (a FAERS row has no sentence to host attachment), and an
  always-blank backing column would encode nothing.
- Every qualifier emits `nullable: true`: the columns are sparse by construction,
  and Tablassert's nullable semantics keep the edge when a cell is blank or
  unresolved, omitting only the qualifier.
- New `_QUALIFIER_GUARD` replaces the hardcoded Disease-only guard: class-ranged
  slots carry a category allow-list matching their Biolink range
  (Disease / AnatomicalEntity / BiologicalSex / PopulationOfIndividualOrganisms),
  while the type-ranged slots (frequency_qualifier: UO `frequency value`;
  temporal_context_qualifier: `xsd:string` `time type`) carry none — no Categories
  member names an honest allow-list for their values, so resolution falls through
  the fullmap with nullable keeping the edge on misses.
- species_context_qualifier stays unwired: Tablassert deliberately disables it
  (DISABLED_EDGE_FIELDS — config load rejects a manual declaration); taxon context
  is auto-derived from node metadata instead.
- Grant tripwire widened: the test now pins all six granted slots on both pinned
  classes, so a Tablassert downgrade fails at test time instead of silently
  pruning the stack off every edge at build time.
- tables/*.yaml regenerated (the suite enforces byte-equality; graph.yaml's RIG
  consideration now names the #188 grant).

Verification: `uv run pytest` -> 1131 passed (coverage 99.89% locally, misses are
the pre-existing aria2c/loopback network-gated lines CI executes); `ruff check` +
`ruff format --check` + `pyright` clean; each regenerated Section validates
against the installed tablassert 19.0.0 (`Section.model_validate`) with the
expected nullable/guard shape on all three tables.
SkyeAv added a commit to glusman-team/dakp that referenced this pull request Sep 15, 2026
…nfigs (#29)

Tablassert 19.0.0's CLASS_FIELD_OVERRIDES grant (SkyeAv/Tablassert#188) keeps
DAKP's five sparse qualifier slots on the pinned association classes through
prune_to_class — the upstream unblock the qualifier columns were waiting for.
Wire them now that the grant exists.

- `_TABLE_QUALIFIERS`: approved-treats and contraindication tables declare
  `anatomical_context_qualifier` / `sex_qualifier` / `population_context_qualifier`
  / `frequency_qualifier` / `temporal_context_qualifier`, each backed by the
  assertion column its sentence-hosted attachment (contexts.attach_qualifiers)
  already populates. The FAERS table declares none: its writer populates no
  qualifier column (a FAERS row has no sentence to host attachment), and an
  always-blank backing column would encode nothing.
- Every qualifier emits `nullable: true`: the columns are sparse by construction,
  and Tablassert's nullable semantics keep the edge when a cell is blank or
  unresolved, omitting only the qualifier.
- New `_QUALIFIER_GUARD` replaces the hardcoded Disease-only guard: class-ranged
  slots carry a category allow-list matching their Biolink range
  (Disease / AnatomicalEntity / BiologicalSex / PopulationOfIndividualOrganisms),
  while the type-ranged slots (frequency_qualifier: UO `frequency value`;
  temporal_context_qualifier: `xsd:string` `time type`) carry none — no Categories
  member names an honest allow-list for their values, so resolution falls through
  the fullmap with nullable keeping the edge on misses.
- species_context_qualifier stays unwired: Tablassert deliberately disables it
  (DISABLED_EDGE_FIELDS — config load rejects a manual declaration); taxon context
  is auto-derived from node metadata instead.
- Grant tripwire widened: the test now pins all six granted slots on both pinned
  classes, so a Tablassert downgrade fails at test time instead of silently
  pruning the stack off every edge at build time.
- tables/*.yaml regenerated (the suite enforces byte-equality; graph.yaml's RIG
  consideration now names the #188 grant).

Verification: `uv run pytest` -> 1131 passed (coverage 99.89% locally, misses are
the pre-existing aria2c/loopback network-gated lines CI executes); `ruff check` +
`ruff format --check` + `pyright` clean; each regenerated Section validates
against the installed tablassert 19.0.0 (`Section.model_validate`) with the
expected nullable/guard shape on all three tables.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant