Result And Refusal Semantics¶
Bijux distinguishes a completed scientific result, a partial record, an input refusal, and an execution failure. Consumers must preserve that distinction across Python, CLI, JSON, TSV, manifests, and reports.
Read Two Layers Of State¶
flowchart LR
transport["Interface outcome<br/>return or exit"] --> scientific["Scientific state<br/>complete · partial · refused · failed"]
scientific --> diagnostics["Code, details,<br/>warnings and inventory"]
diagnostics --> decision["Consumer acceptance<br/>for one claim"]
The interface layer answers whether the call or command was handled. The scientific layer answers whether the requested analysis produced an interpretable result. A valid JSON response can describe a refused analysis; an exception can preserve useful preflight or partial-run evidence.
Stable Python Failures¶
Runtime failures derive from PhylogeneticsError and carry three parts:
| Field | Meaning | Consumer action |
|---|---|---|
| exception type | broad failure family, such as tree parsing, metadata joining, comparative analysis, or engine execution | choose the recovery owner |
code |
stable machine-readable reason | branch automation on the code, not prose |
details |
structured paths, engines, missing outputs, evidence, or blocking facts | retain with the failed run |
The message is for people and may become clearer over time. Do not parse it as
a compatibility contract when code and details carry the same fact.
Representative families include invalid tree or alignment input, duplicate or unnamed taxa, metadata joins, non-ultrametric or unrooted trees, unavailable external engines, blocked engine workflows, comparative or ancestral model errors, evidence-contract violations, and workflow-budget refusals.
Classify Before Recovery¶
| State | Defining observation | Legitimate next action |
|---|---|---|
| refused before execution | input, policy, capability, or preflight contract was not met | correct the owning input or configuration and create a new run identity |
| failed during execution | computation or infrastructure stopped before the required terminal record | preserve partial files and diagnostics; retry only under a declared rule |
| partial | valid components exist but the declared inventory or diagnostic threshold is incomplete | restrict the claim or execute the missing component |
| complete | all declared components and terminal diagnostics exist | apply the scientific acceptance rule |
| accepted for a claim | a consumer approved one bounded interpretation | retain claim scope and decision provenance |
“Complete” is not synonymous with “accepted.” A numerically complete result can be unsuitable because its taxon population, convergence, support, sensitivity, or model assumptions do not satisfy the intended claim.
Treat Terminal State As An Evidence-Preserving State Machine¶
stateDiagram-v2
[*] --> validating
validating --> refused: input, policy, or capability boundary
validating --> executing: preflight admitted
executing --> failed: computation or infrastructure stops
executing --> partial: valid record lacks a required component
executing --> complete: declared inventory and terminal diagnostics exist
complete --> accepted: consumer rule passes for one bounded use
partial --> accepted: consumer explicitly narrows the use
refused --> [*]
failed --> [*]
partial --> [*]
complete --> [*]
accepted --> [*]
The terminal producer state is immutable evidence. A retry creates a sibling
run; it does not turn the earlier failed record into complete. A consumer
may accept a partial result for a narrower purpose, but that child decision
must preserve the missing components and cannot rewrite the producer status.
Retain The Requested, Executed, And Accepted Populations¶
Batch and repeated workflows need three denominators. Counting only successful outputs makes failures and selective acceptance disappear.
| Population | Members | Question answered |
|---|---|---|
| requested | every declared taxon set, replicate, model, start, chain, engine case, or artifact | what work and coverage were promised? |
| executed | every admitted attempt, including failed and partial terminal states | what actually ran and how did it terminate? |
| accepted | results a consumer admits for one bounded use, plus explicit rejections | what supports the downstream decision? |
The populations may differ, but their transitions must be row-addressable. A refused request stays in the requested denominator; a failed attempt stays in the executed denominator; a complete result rejected for poor diagnostics stays outside acceptance with its reason. Retrying adds an attempt—it does not reduce the failure count or original requested population.
| Transition request | Correct treatment |
|---|---|
| refused input is corrected | create a new run with the corrected input identity |
| failed engine execution is retried | retain the failed attempt and link the retry policy and new run |
| missing component arrives later | create or revise a governed record with explicit lineage; do not silently mutate an archived bundle |
| complete result fails a scientific threshold | preserve complete; record rejection for the bounded claim |
| partial result is useful for diagnosis | accept only the diagnostic use and prohibit unsupported scientific conclusions |
External-Engine Incomplete Runs¶
Engine workflows retain executable, workflow, working directory, command,
streams, timestamps, timeout state, exit code, declared outputs, missing output
names, and observed-file checks. The default incomplete_run_policy="reject"
prevents a partial native artifact from silently becoming a normal result.
Changing that policy affects scientific state. Preserve why an incomplete artifact was admitted, which fields remain unavailable, and which conclusions are forbidden. Never convert an engine exit code into a success merely because a tree-like file exists.
Preserve Unknown And Inapplicable Values¶
An absent value can mean not requested, not applicable, not observed, failed to compute, excluded, or not comparable. These meanings require different states. Do not serialize all of them as zero, an empty string, or a dropped row.
TSV is useful for review but may be less expressive than the typed result and JSON record. Keep the richer owner whenever null reason, warning identity, nested diagnostics, or missing-output state affects interpretation.
Consumer Acceptance Record¶
A downstream consumer should record the source result identity, observed scientific state, codes and warnings reviewed, required inventory, acceptance rule, accepted claim scope, excluded interpretations, and reviewer or process identity. That record is new provenance; it must not rewrite the producer's state.
If an interface cannot carry a material refusal or diagnostic, stop at that boundary or retain a link to the richer record. Silent loss of failure state is more dangerous than an explicit refusal to serialize.