# BioWeaver evidence graph, version 1

The browser Graph Explorer and free `bioweaver-client` Python package exchange UTF-8 JSON
documents. This is a portable evidence document, not a paid API contract or signed archive.

## Envelope

| Field | Required value or structure |
| --- | --- |
| `format` | `bioweaver-evidence-graph` |
| `schemaVersion` | integer `1` |
| `snapshots` | `{trail: fullManifest, orthology: fullManifest}` |
| `inputs` | ordered input occurrences `{line, token, taxon, resolution}` |
| `subjects` | unique loaded `{gene, data: {disease: [...]}}` entries |
| `orthology` | original directed orthology candidate records |
| `view` | `{state, query, references, donors, start, selected}` |

Manifests use the existing snapshot schema, version 1. Each artifact entry includes `path`,
`bytes`, `sha256`, `schemaVersion`, and `datasetId`. Artifact paths are safe relative JSON
filenames. Trail's `dependencies.orthology` must equal Orthology's `datasetId`. Downloads
are checksum-verified before use; imports are structurally validated. Neither procedure
authenticates a publisher independently of the supplied manifest. Expansion of an imported
graph requires the same manifests as the configured snapshot roots.

## Inputs and records

`line` is a positive unique input-occurrence number; it is not a gene ID. Repeated tokens
remain separate inputs. `taxon` is a string taxon ID from the snapshot catalogue.
`resolution` retains `input` (the original token), `status`, `method`, and unique `candidates`.
A resolved input has exactly one candidate and its matching loaded subject. Ambiguous inputs
have at least two candidates; unresolved inputs have none. Resolution methods are `stable_id`,
`symbol`, `alias`, or `case_folded`; unresolved method is null. No implicit history substitution
or user-choice acceptance is performed by this format's resolver.

`gene` retains the catalogue record and must include nonempty `id`, `taxon`, and `symbol`.
Subjects are unique by `(taxon, id)`. An empty disease array is a source-scoped lack of matched
records, not a negative biological finding or a statement that no research exists.

Disease records retain `diseaseId`, `disease`, `state`, `relation`, `references`, `donors`,
`evidence`, and any other original fields. References are identifier strings. Donors include
`id`, `taxon`, `symbol`, and, when recorded, boolean `curatedExactTerm`. Unknown states remain
unknown; `curated`, `inferred`, and `negative` must never be combined or inferred from counts.
If `subjectTaxon` is present, it must match the containing gene's taxon.

Orthology records retain `sourceId`, `sourceTaxon`, `targetId`, `targetTaxon`, numeric
nonnegative `support`, string-array `methods`, and all other original fields, including
`outOf`, `best`, and `bestReverse`. Both endpoints must be loaded subjects. These are candidates
from the exported stringent subset, not guarantees of functional equivalence. Missing pair
artifacts are unavailable data; a verified empty match is no record within that subset.

## Graph identity and meaning

Node IDs are JSON-serialized arrays:

- Gene: `["gene", taxon, geneId]`.
- Annotation: `["annotation", trailDatasetId, taxon, geneId, zeroBasedAnnotationIndex]`.
- Disease: `["disease", diseaseId]`.
- Reference: `["reference", referenceId]`.

Annotation identities preserve duplicate occurrences within one snapshot and gene; they are
not stable annotation IDs across releases. Rendering adds `subject_of`, `annotated_to`,
`names_reference`, `names_donor`, and `ortholog_candidate` connections. A donor and reference
co-occurring in an annotation do not imply a donor-reference pairing. Several annotations
naming one reference do not establish independent studies. Layout distance has no biological
meaning. Rendered edge IDs are local to a view and are not persisted evidence identities.

## View and limits

`state` defaults to `all`; other strings match exact record states. `query` is a case-insensitive
substring filter over gene symbol/ID and disease name/ID. `references` and `donors` are booleans.
`start` is a nonnegative annotation offset; the browser clamps it to a page boundary.
`selected` is null or a node identity string. Invisible selections are cleared when rendered.

Document limits: 20 inputs, 40 subjects, 2,000 orthology edges, 20,000 disease annotation
occurrences, and 25 MiB serialized JSON. Identity strings and query text are bounded at 10,000
characters. Exceeding document limits fails; evidence is never silently truncated to fit.

Rendering is separately bounded at 25 annotation occurrences per page and 12 references plus
12 donor entries per displayed annotation. The interface reports omitted context links.
The saved document retains all loaded evidence and input decisions irrespective of filtering.
Filtered TSV includes all matching annotations across pages. PNG includes the displayed
network, scope counts and snapshot IDs; it is not the complete evidence archive.

## Python usage

Install `libraries/python` from a checkout, or download the source package linked by the
Graph Explorer developer page. The package is not on PyPI. Public usage instructions and a
source archive are built at `/graph/developer.html` and `/graph/bioweaver-client.tar.gz`.
The client accepts local directories or explicit HTTP(S) snapshot roots. `Client.graph()`
and `Client.expand()` generate this format; `read_document()` and `write_document()` validate
it locally. The package's MIT license covers client code only, not upstream datasets.
