Skip to content

Fix CladeCumulus testset: field names, NHX capture, LWR tolerance, route loading - #222

Merged
hyperpolymath merged 2 commits into
mainfrom
arena/86bcd6f5-metamanifold-webui
Oct 23, 2026
Merged

hyperpolymath merged 2 commits into
mainfrom
arena/86bcd6f5-metamanifold-webui

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Follow-up to #214/#218. With the frontend, differential and validated-statistics suites green, the Julia suite stands at 817 pass / 3 fail / 14 error — every remaining failure inside the CladeCumulus testset from #207, masked until now by the broken build.

  • _graft_jplace_queries read QueryCandidate.weight/.distal_length/.pendant_length; the fields are like_weight/distal_len/pendant_len (FieldError on any valid graft).
  • PLACEMENT_WEIGHT_SUM_TOL = 1e-5 marked a single retained placement at LWR 0.98 undecided; truncated candidate lists legitimately sum to slightly less than 1, so tolerance is 0.05 (0.40 still undecided).
  • The Newick label reader consumed [&&NHX:B=92] after ) without capturing it; capture refs are threaded through read_label_and_quoted.
  • The sources route enumerated views via SHOW TABLES and then could not bind a session-registered DataFrame view on a fresh connection (500); it now uses duckdb_tables().
  • _load_run_table_df rejected JSON3 SubString table names; arguments normalise to String at the boundary.
  • The FastTree mock in tests addressed PH.Tools, but Phylogeny imports only selected names from Tools; it now addresses MetaManifold.Tools.

Julia evidence is CI on this PR (no Julia runtime in the authoring sandbox).

…rance, route table loading

The CladeCumulus testset (the last red testset in the Julia suite:
817 pass / 3 fail / 14 error, all inside it) shipped in #207 with
defects that the long-broken build had masked:

- _graft_jplace_queries read QueryCandidate.weight/.distal_length/
  .pendant_length; the struct fields are like_weight/distal_len/
  pendant_len (FieldError on any valid jplace graft).
- A single retained placement at LWR 0.98 was marked undecided:
  PLACEMENT_WEIGHT_SUM_TOL=1e-5 rejects truncated candidate lists
  whose retained ratios legitimately sum to slightly less than 1.
  Tolerance is now 0.05; a 0.40 sum stays undecided.
- The Newick label reader consumed an NHX comment after ')' without
  capturing it, dropping [&&NHX:B=92] support; capture refs are now
  threaded through read_label_and_quoted.
- The sources route listed views via SHOW TABLES and then failed to
  bind a session-registered DataFrame view on a fresh connection
  (500); it now enumerates real tables via duckdb_tables().
- _load_run_table_df rejected the SubString table names JSON3
  returns; arguments are normalised to String at the boundary.
- Test used PH.Tools, but Phylogeny imports only selected names from
  Tools; the mock-tool override now addresses MetaManifold.Tools.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
@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-23T07:29:48.134639Z b6ab932 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.

@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 48 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: 718c4d4c-2e00-4127-8b83-783c96e2394a
📥 Commits

Reviewing files that changed from the base of the PR and between 8b76b71 and 0e409ed.

📒 Files selected for processing: 4
  • src/analysis/clade_cumulus.jl
  • src/core/doi.jl
  • src/server/routes/clade_cumulus.jl
  • 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.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Fork governance

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

Hypatia grid purple

🟣 critical · commit 0e409ed7791b · run 39918622786

Reporter Status Critical High Medium Minor Since previous revision
Hypatia scan 🟣 critical 43 59 31 0 ↔ unchanged
panic-attack assail 🔴 high 0 6 13 0 ↔ unchanged
pons asinorum 🟡 medium 0 0 10 0 ↔ unchanged
rhodibot (RSR compliance) 🟠 indeterminate 0 0 0 0 — indeterminate
panicbot (panic recovery, error handling) 🟠 indeterminate 0 0 0 0 — indeterminate
echidnabot (formal verification: proofs/) 🟠 indeterminate 0 0 0 0 — indeterminate
seambot (integration health: API routes) 🟠 indeterminate 0 0 0 0 — indeterminate
finishingbot (release readiness) 🟠 indeterminate 0 0 0 0 — indeterminate
accessibilitybot (WCAG on the React UI) 🟠 indeterminate 0 0 0 0 — indeterminate
glambot (presentation quality) 🟠 indeterminate 0 0 0 0 — indeterminate
cipherbot ⚪ not applicable 0 0 0 0 ↔ unchanged
sustainabot ⚪ not applicable 0 0 0 0 ↔ unchanged
Hypatia scan: 133 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
  • 113 more; see the structured report in the artifact.
panic-attack assail: 19 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/tree/model.ts — 1 JSON.parse call(s) with 0 try block(s) in frontend/src/tree/model.ts — JSON.parse throws SyntaxError on malformed input; wrap in try-catch
  • medium InputBoundary — frontend/src/api/events.ts — 2 JSON.parse call(s) with 0 try block(s) in frontend/src/api/events.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: 10 finding(s)
  • medium string-concat-in-loop — ./frontend/src/tree/model.ts:122 — string built by repeated concatenation in a loop (T0, HEURISTIC)
  • medium string-concat-in-loop — ./frontend/src/tree/model.ts:118 — string built by repeated concatenation in a loop (T0, HEURISTIC)
  • 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b6ab9325b8

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# like-weight ratios can legitimately sum to slightly less than 1 (a single
# retained placement at 0.98 is complete evidence). Sums far from 1 indicate
# a malformed or partial record and stay undecided.
const PLACEMENT_WEIGHT_SUM_TOL = 0.05

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject placement weights that exceed one

When candidate LWRs total between 1.0 and 1.05 (for example, 0.60 + 0.44), the existing abs(weight_sum - 1.0) check now marks the query valid. Truncating a candidate list can only lower its retained mass, so the widened tolerance should apply only below 1.0; otherwise malformed overweight records are accepted and subsequently normalized into apparently valid placement evidence.

Useful? React with 👍 / 👎.

for q in jd.queries
q.status === :valid && !isempty(q.candidates) || continue
total_w = sum((c.weight for c in q.candidates); init = 0.0)
total_w = sum((c.like_weight for c in q.candidates); init = 0.0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate the corrected LWR field into the HTTP route

For a CladeCumulus POST using a valid .jplace file and a table with sample columns, this fix lets _graft_jplace_queries complete, but the ensuing diversity block in src/server/routes/clade_cumulus.jl:279-285 still reads c.weight and cand.weight. QueryCandidate has only like_weight, so the advertised HTTP flow still raises a FieldError and returns a 500 instead of the analysis response.

Useful? React with 👍 / 👎.

Comment on lines +70 to +71
study = String(study); run = String(run); table = String(table)
group = isnothing(group) ? nothing : String(group)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize the selected tree filename too

When either POST route uses treeSource: "study_tree", tree_file = strip(string(...)) in _resolve_tree_inputs_from_request is a SubString, while _valid_tree_file and _tree_format in routes/trees.jl accept only String. Normalizing the table arguments only inside this loader allows the request to advance to that next MethodError, so existing .nwk and .jplace selections still fail before the tree is read; normalize tree_file as well or broaden those helper signatures.

Useful? React with 👍 / 👎.

src/core/doi.jl ended with 'end # module DOI' but never opened the
module, so including it into MetaManifold failed to parse
(ParseError at doi.jl:681) and no Julia test could even load the
package. Routes and tests address MetaManifold.DOI, so the file is
a submodule whose opener was lost in an earlier repair.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
@hyperpolymath
hyperpolymath merged commit 8df1041 into main Oct 23, 2026
12 checks passed
@hyperpolymath
hyperpolymath deleted the arena/86bcd6f5-metamanifold-webui branch October 23, 2026 07:34
@sonarqubecloud

Copy link
Copy Markdown

hyperpolymath added a commit that referenced this pull request Oct 23, 2026
Bring in #222's DOI/module and CladeCumulus repairs, retain valid source-table enumeration, and reject overweight jplace queries while allowing truncated weight shortfalls.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
hyperpolymath added a commit that referenced this pull request Oct 23, 2026
CI on `main` (8df1041) shows `POST /clade-cumulus` answering 500 for
every `study_tree` request:

    MethodError: no method matching _valid_tree_file(::SubString{String})

`JSON3` hands request fields back as `SubString`s and `strip` keeps them
that way, but `_valid_tree_file` and `_tree_format` in `routes/trees.jl`
are `String`-typed. The handler has no catch around
`_resolve_tree_inputs_from_request`, so the MethodError surfaced as a
500 and took seven assertions down with it: `r_comb.status == 200`
failed, and every `comb.*` access after it raised `KeyError` until the
testset aborted.

#222 fixed this class at `_load_run_table_df` -- "JSON3 hands request
fields back as SubStrings; the DuckDB helpers are String-typed, so
normalise once at this boundary" -- but `_resolve_tree_inputs_from_request`
two functions below kept the unnormalised values. `cladistics.jl`
already wraps its own call as `_valid_tree_file(String(published))`, so
the convention is to normalise at the call site; this follows it.

The existing `r_comb` assertion is the regression test: it sends
`"treeFile" => "amplicon.nwk"` over JSON, which is exactly the SubString
path that broke.

With the `u.edge_num` -> `u.edge_number` repair already carried in from
#223, this accounts for 8 of the 9 errors that run reported.
hyperpolymath pushed a commit that referenced this pull request Oct 23, 2026
Builds on #222, which fixed the graft query fields but left three sites:

- `_graft_jplace_queries` still constructed `PhyloNode(..., u.edge_num, ...)`
  and read `u.edge_num` when matching placements to edges. The field is
  `edge_number`, so any graft threw `FieldError` before the tree was rebuilt
  ("Got exception outside of a @test" — no test line, which is why it read
  as an unrelated suite failure).
- The diversity block in the route still summed `c.weight` over jplace
  candidates. `QueryCandidate` carries `like_weight`; reading `.weight` threw
  inside the handler, and with `show_errors=false` the POST answered a bare
  500, so every assertion on the combined-mode payload failed with
  `KeyError: key :root not found`.
- `routes/cladistics.jl` was included twice in server.jl, registering every
  /cladistics route twice.

`cand.edge_num` stays: that is the `QueryCandidate` field. The undirected
edge struct's `edge_no` and its `weight` are separate types.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
hyperpolymath added a commit that referenced this pull request Oct 23, 2026
…d syntax checks

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
hyperpolymath added a commit that referenced this pull request Oct 23, 2026
## What this is

#217 (`fix(stats): aggregate DuckDB counts exactly`) has been
`CONFLICTING`
since main moved: #218 fixed the same run-summaries 500 independently,
#210
repaired the differential/analysis modules, #220 removed the Evidence
UI, and
#222 repaired the CladeCumulus tree/route code. This branch merges the
current
main into #217's head, resolves every conflict, and repairs the two
main-line
defects that were failing the required `Julia tests` check on *both*
branches.
It contains #217's content in full, so merging it lands #217.

## Conflict resolution (4 files)

- `src/server/routes/validated_statistics.jl` — **the PR's
implementation is
  kept unchanged.** Main's #218 kept a `GROUP BY`-free `ORDER BY … LIMIT
MAX_CELLS+1` window and scanned only the `counts` member for float
tokens;
#217 streams the raw rows, bounds features/cells *as rows arrive*, and
scans
the whole direct body. Nothing main added after 7bb716d was lost: the
two
  versions differed only in those four hunks.
- `test/unit/test_validated_statistics.jl` — union. Main's `(1.5, -1,
2^53+1)`
  Dict cases and its `1.0`/`1e0` raw-token loop are kept next to #217's
byte-backed `Vector{UInt8}` cases and its `round_digits: 8.0` rejection,
so
  both sides' contracts are now tested.
- `test/unit/test_exact_summaries.jl` — main's wording; same assertions.
- `.github/workflows/ci.yml` — main's log path/title with #217's
ordering that
  runs the validated-statistics suite first.

The CladeCumulus merge takes **main's** #222 implementation (real tables
only
via `duckdb_tables()`, `SubString` normalisation at the request
boundary, NHX
capture, `PLACEMENT_WEIGHT_SUM_TOL = 0.05`) and keeps the two repairs
#222
still lacks: `PhyloNode.edge_number` in `_graft_jplace_queries` (main
reads a
field that does not exist) and the connecting branch in
`_reaggregate_after_move`, so a subtree PD agrees with `clade_faith_pd`.

## Two main-line fixes needed to get the required checks green

1. **`UndefVarError: erfc`** — `CompositionalModels._wald` called `erfc`
   without importing or defining it, so every multinomial / Dirichlet-
multinomial fit raised on any tree where it could load. The module
states it
   carries its own special functions so the models add no dependency, so
`_erfc` is added in the same style: `erfc(t) = Q(1/2, t²)`, power series
   below the switch, continued fraction above it (modified Lentz).
2. **`DifferentialConfig(…, min_prevalence=1.0)`** — the test passed
`min_prevalence` as a keyword; it is positional in the constructor and
in
   the route that builds it. Fixed in the test.

## Validation

- DuckDB (independent of Julia): the old grouped query fails with
`column "s1" must appear in the GROUP BY clause…`; the streamed query
returns
`G → [3, 2^127]`, `H → [4, 1]`, and the `prefix=s2` + `Pident ≥ 99`
filter
  returns `s2 → 2^126`, exactly the values the tests assert.
- The integer-token scanner was ported line-for-line and run over the
test
bodies: `1.0`, `1e0`, `3.0e-1` and `round_digits: 8.0` are refused;
integer
tokens, quoted `"1.0"`, escapes and digits inside strings are accepted;
the
  run route (which legitimately takes `Pident: 99.0`) is not scanned.
- `_erfc` was checked against libm's `erfc` on `t ∈ [0, 30]`: worst
relative
  error 1.5e-13, and the two-sided tail reproduces this file's p-value
  references to 1.5e-12 (the test asserts `rtol = 1e-6`).
- All 122 `src/**.jl` and `test/**.jl` files parse with a Julia grammar;
the
  three files that still show grammar nodes (`remote_exec.jl`,
`occupancy_disagreement_test.jl`, `test_determinism.jl`) are untouched
here.
- `git diff --check` clean; `.github/workflows/ci.yml` parses as YAML.
- Julia itself is not installable in this sandbox (the toolchain
download host
is blocked), so the pinned suite has to be the authority: this PR exists
to
  give CI the merged tree to run on.

## Relationship to #217

Merging this lands #217's content. To make #217 itself mergeable
instead, its
head must be advanced to this branch; that is a single command for
someone who
can push to it:

```
git push origin arena/a8928088-metamanifold-webui:arena/dd990535-metamanifold-webui
```

---------

Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
hyperpolymath added a commit that referenced this pull request Oct 23, 2026
Main landed #226, which contains equivalents of this branch's
_erfc implementation, min_prevalence test fix, edge_number graft
fix and stem-inclusive subtree PD, plus #217's validated-statistics
implementation and the CLADE_SV rename that removes the Main.SV
const collision. Conflicts resolved in favour of main for those;
this branch keeps its unique additions: AbstractString tree
helpers and the structured clade_cumulus_failed catch-all with the
like_weight diversity fixes.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
hyperpolymath added a commit that referenced this pull request Oct 23, 2026
Follow-up to #222 (merged before this commit arrived). The Julia suite
on #222 reached 825 pass / 1 fail / 9 error, all remaining in
CladeCumulus, from two root causes:

- The jplace graft walk read `u.edge_num`/`cur.edge_num`; `PhyloNode`'s
field is `edge_number` (`QueryCandidate.edge_num` is a different,
legitimate field). Grafting any valid placement threw FieldError.
- `_valid_tree_file` only accepted `::String`, but `strip()` of a
request field yields a `SubString`, so POST clade-cumulus with
`treeSource: study_tree` returned 500. It now accepts `AbstractString`.

Julia evidence is CI on this PR.

---------

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
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