Skip to content

Pin the weighted-UniFrac expectation to the library-size definition (green Julia tests on main) - #240

Merged
hyperpolymath merged 1 commit into
mainfrom
arena/a4bb67df-metamanifold-webui
Oct 23, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
arena/a4bb67df-metamanifold-webui

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

main is red on Julia tests — 5727 pass, 1 fail, 0 error — and it was already red when #239 merged: that PR's own Julia tests check failed on the same line.

Dual-hierarchy CladeCumulus, polyphyly detection, drag-and-drop, and HTTP routes: Test Failed at test/unit/test_clade_cumulus.jl:730
  Expression: ≈((jp_body.diversity.weighted_unifrac[1])[2], 0.15636363636363637, atol = 1.0e-9)
   Evaluated: 0.1378181818181818 ≈ 0.15636363636363637

Which number is right

The expectation predates #239's own fix, which its description states as "totals/total_a/total_b library-size denominators". The route now divides by each sample's 55-read library instead of the 34 and 20 reads that happened to reach the tree, which is the whole point of that change — otherwise the unplaced mass is renormalised back onto the tips.

Working the fixture out from that definition, for the grafted tree of ((Ref_1:0.10{0},Ref_2:0.20{1})0.96:0.30{2},Ref_3:0.40{3}){4}; with ASV_1 placed at LWR 0.60 on edge 0 (distal 0.05, pendant 0.02) and ASV_2 at LWR 1.00 on edge 1:

edge length SampleA (24 / 10 placed) SampleB (20 placed)
ASV_1 pendant 0.02 24/55 0
Ref_1 remainder 0.05 24/55 0
ASV_2 pendant 0.02 10/55 20/55
Ref_2 remainder 0.15 10/55 20/55
joining clade 0.30 34/55 20/55
Ref_3 0.40 0 0
raw weighted UniFrac = (0.02*24 + 0.05*24 + 0.02*10 + 0.15*10 + 0.30*(34-20)) / 55
                     = 7.58 / 55 = 0.1378181818...

That is exactly what the route returns, so the code agrees with its documented definition and the constant is stale. Nothing else in the block changes: mapped_tips == 2, unplaced_reads 21/35 and root.cumulative_count ≈ 110 all still hold, and no other test in the suite fails.

Change

One test assertion. It now spells out the arithmetic — ≈ 7.58 / 55 with the edge-length derivation in a comment — so a future convention change has to argue with the definition rather than with a bare decimal. No production code is touched.

Verified

The full suite on this branch is CI; locally, tree-sitter parses the edited statement and git diff shows only the assertion. Everything else on main (including #238's rooting tests) passed in the run that caught this.

`Julia tests` on `main` is red on one assertion, and it was already red when
#239 merged: that PR's own `Julia tests` check failed with the same line.

    Dual-hierarchy CladeCumulus, ...: Test Failed at test_clade_cumulus.jl:730
      Expression: ≈((jp_body.diversity.weighted_unifrac[1])[2], 0.15636363636363637)
       Evaluated: 0.1378181818181818 ≈ 0.15636363636363637

The expectation predates #239's `totals` plumbing. That PR's stated fix is
"totals/total_a/total_b library-size denominators", and the code now divides
by the 55-read library rather than the 34/20 reads that reached the tree. The
value follows directly from that definition — the grafted tree contributes
0.02 (ASV_1's pendant), 0.05 (the rest of Ref_1's branch), 0.02 (ASV_2's
pendant), 0.15 (the rest of Ref_2's branch) and 0.30 (the joining clade):

    (0.02*24 + 0.05*24 + 0.02*10 + 0.15*10 + 0.30*(34-20)) / 55
      = 7.58 / 55 = 0.1378181818...

which is exactly what the route returns. The assertion now states the
arithmetic, so the next convention change has to argue with it rather than
with a bare decimal.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 7 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: e6162fc1-5c01-486b-a1db-88e408c9ca38
📥 Commits

Reviewing files that changed from the base of the PR and between f0a4ad5 and ab5451a.

📒 Files selected for processing: 1
  • test/unit/test_clade_cumulus.jl
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T15:54:08.309797Z ab5451a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Add Carrot credits or activate Agent usage billing to use Autofix

@github-actions

Copy link
Copy Markdown

Fork governance

Lane Status Run
DEED syntax (repo deed) 🟢 conformant run 39982034066
Hypatia verdict grid purple (job: success) same run

Hypatia grid purple

🟣 critical · commit ab5451a54125 · run 39982034066

Reporter Status Critical High Medium Minor Since previous revision
Hypatia scan 🟣 critical 45 61 35 0 — no comparable baseline
panic-attack assail 🔴 high 0 6 11 0 — no comparable baseline
pons asinorum 🟡 medium 0 0 8 0 — no comparable baseline
rhodibot (RSR compliance) 🟠 indeterminate 0 0 0 0 — no comparable baseline
panicbot (panic recovery, error handling) 🟠 indeterminate 0 0 0 0 — no comparable baseline
echidnabot (formal verification: proofs/) 🟠 indeterminate 0 0 0 0 — no comparable baseline
seambot (integration health: API routes) 🟠 indeterminate 0 0 0 0 — no comparable baseline
finishingbot (release readiness) 🟠 indeterminate 0 0 0 0 — no comparable baseline
accessibilitybot (WCAG on the React UI) 🟠 indeterminate 0 0 0 0 — no comparable baseline
glambot (presentation quality) 🟠 indeterminate 0 0 0 0 — no comparable baseline
cipherbot ⚪ not applicable 0 0 0 0 — no comparable baseline
sustainabot ⚪ not applicable 0 0 0 0 — no comparable baseline
Hypatia scan: 141 finding(s)
  • critical cicd_rules/banned_language_file — frontend/src/views/run/parseFilterYaml.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/figure/encode.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/figure/charts.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/figure/export.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/figure/figure.test.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/figure/legend.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/figure/types.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/utils/download.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/utils/text.test.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/utils/timeago.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/utils/text.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/hooks/useUnsavedGuard.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/hooks/useApi.test.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/hooks/useApi.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/hooks/useAnalysis.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/hooks/useSSE.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/hooks/useTabParam.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/hooks/useNavRefresh.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/hooks/useJobEvents.ts — TypeScript file detected -- banned language
  • critical cicd_rules/banned_language_file — frontend/src/about.ts — TypeScript file detected -- banned language
  • 121 more; see the structured report in the artifact.
panic-attack assail: 17 finding(s)
  • high DynamicCodeExecution — src/pipeline/dada2/context.jl — eval/Meta.parse in src/pipeline/dada2/context.jl
  • high DynamicCodeExecution — src/analysis/analysis.jl — eval/Meta.parse in src/analysis/analysis.jl
  • high DynamicCodeExecution — src/analysis/differential.jl — eval/Meta.parse in src/analysis/differential.jl
  • high DynamicCodeExecution — src/core/provenance.jl — eval/Meta.parse in src/core/provenance.jl
  • high DynamicCodeExecution — scripts/check-julia-syntax.jl — eval/Meta.parse in scripts/check-julia-syntax.jl
  • high DynamicCodeExecution — test/unit/test_permanova.jl — eval/Meta.parse in test/unit/test_permanova.jl
  • medium UnsafeFFI — src/core/memory_probe.jl — 3 ccall/FFI calls in src/core/memory_probe.jl
  • medium InputBoundary — src/server/routes/runs.jl — 2 JSON3.read/JSON.parse call(s) with 0 try block(s) in src/server/routes/runs.jl — these throw on malformed input; wrap in try/catch
  • medium InputBoundary — src/server/routes/composition.jl — 6 JSON3.read/JSON.parse call(s) with 2 try block(s) in src/server/routes/composition.jl — these throw on malformed input; wrap in try/catch
  • medium InputBoundary — src/server/routes/studies.jl — 4 JSON3.read/JSON.parse call(s) with 2 try block(s) in src/server/routes/studies.jl — these throw on malformed input; wrap in try/catch
  • medium InputBoundary — src/server/routes/analysis.jl — 9 JSON3.read/JSON.parse call(s) with 4 try block(s) in src/server/routes/analysis.jl — these throw on malformed input; wrap in try/catch
  • medium UnsafeFFI — install.jl — 1 ccall/FFI calls in install.jl
  • medium ProofDrift — test/unit/test_occupancy_grade.jl — 2 `@test x isa Y` assertion(s) with no value check — type-only tests may substitute for an unwritten formal theorem in test/unit/test_occupancy_grade.jl
  • medium ProofDrift — test/unit/test_evidence.jl — 1 `@test x isa Y` assertion(s) with no value check — type-only tests may substitute for an unwritten formal theorem in test/unit/test_evidence.jl
  • medium InputBoundary — bench/advanced_zero_handling/benchmark.jl — 1 JSON3.read/JSON.parse call(s) with 0 try block(s) in bench/advanced_zero_handling/benchmark.jl — these throw on malformed input; wrap in try/catch
  • medium InputBoundary — frontend/src/figure/charts.ts — 1 JSON.parse call(s) with 0 try block(s) in frontend/src/figure/charts.ts — JSON.parse throws SyntaxError on malformed input; wrap in try-catch
  • medium InputBoundary — frontend/src/components/alphaMetrics.tsx — 1 JSON.parse call(s) with 0 try block(s) in frontend/src/components/alphaMetrics.tsx — JSON.parse throws SyntaxError on malformed input; wrap in try-catch
pons asinorum: 8 finding(s)
  • medium string-concat-in-loop — ./frontend/src/tree/TreeShapes.tsx:69 — string built by repeated concatenation in a loop (T0, HEURISTIC)
  • medium string-concat-in-loop — ./frontend/src/tree/TreeShapes.tsx:66 — string built by repeated concatenation in a loop (T0, HEURISTIC)
  • medium string-concat-in-loop — ./frontend/src/tree/TreeShapes.tsx:61 — string built by repeated concatenation in a loop (T0, HEURISTIC)
  • medium string-concat-in-loop — ./frontend/src/tree/TreeShapes.tsx:53 — string built by repeated concatenation in a loop (T0, HEURISTIC)
  • medium string-concat-in-loop — ./frontend/src/tree/TreeShapes.tsx:43 — string built by repeated concatenation in a loop (T0, HEURISTIC)
  • medium string-concat-in-loop — ./frontend/src/tree/TreeShapes.tsx:42 — string built by repeated concatenation in a loop (T0, HEURISTIC)
  • medium unreachable-after-jump — ./frontend/src/figure/PaneEditor.tsx:45 — statement is unreachable after an unconditional jump (T0, HEURISTIC)
  • medium unreachable-after-jump — ./frontend/src/components/PublicationTablesPanel.tsx:208 — statement is unreachable after an unconditional jump (T0, HEURISTIC)
rhodibot (RSR compliance): not_run — enrolled, but no report-back was received
  • 🟠 indeterminate: enrolled, but no report-back was received
panicbot (panic recovery, error handling): not_run — enrolled, but no report-back was received
  • 🟠 indeterminate: enrolled, but no report-back was received
echidnabot (formal verification: proofs/): not_run — enrolled, but no report-back was received
  • 🟠 indeterminate: enrolled, but no report-back was received
seambot (integration health: API routes): not_run — enrolled, but no report-back was received
  • 🟠 indeterminate: enrolled, but no report-back was received
finishingbot (release readiness): not_run — enrolled, but no report-back was received
  • 🟠 indeterminate: enrolled, but no report-back was received
accessibilitybot (WCAG on the React UI): not_run — enrolled, but no report-back was received
  • 🟠 indeterminate: enrolled, but no report-back was received
glambot (presentation quality): not_run — enrolled, but no report-back was received
  • 🟠 indeterminate: enrolled, but no report-back was received
cipherbot: not_applicable — no cryptography is implemented in this repository
  • ⚪ not applicable: no cryptography is implemented in this repository
sustainabot: not_applicable — fleet adapter slot reserved; no adapter exists yet (gitbot-fleet README)
  • ⚪ not applicable: fleet adapter slot reserved; no adapter exists yet (gitbot-fleet README)

Scope: static findings reported by each row's tool at the named commit. Purple, red, yellow and blue grade the worst finding present; orange is evidence missing, malformed or a scanner that did not run; grey is an explicit scope exclusion with its reason. No row is a security certification. report.json, badge.json and the raw findings are in the verdict-grid artifact on the linked run.

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