Ordination coordinates: a sample-id-indexed matrix of PC axis values, plus
the per-axis proportion explained. Either a plain TSV/CSV (#id header then
one row per sample) or an scikit-bio OrdinationResults file, whose Site
block carries the same matrix and whose Proportion explained block carries
the vector.
Sample metadata: a #SampleID header naming the columns, then one row per
sample. Values are strings; numeric coercion happens at use sites (sort,
weighting).
QIIME-style gradient/trajectory ANOVA over a precomputed ordination, the
scikit-bio GradientANOVA family. For each requested metadata category it
builds per-group trajectories through the ordination space and runs one-way
ANOVA across the groups.
Write the gradient ANOVA result as TSV. One block per category: a header line
with the ANOVA probability (or the skip message), then for each group a line
with its mean and the trajectory components.