BIOMD0000001065 flaps between PASS and SOLVER_FAILURE: investigate the fractional-pow-through-zero, and add an INTERMITTENT test status
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
Start in vcell-core/.../sedml/testsupport/OmexTestCase.java where Status is defined, then read the FAIL branch in OmexTestReport that compares known_failure_type against execSummary.failure_type; add INTERMITTENT as a fourth value with a parallel branch that accepts either a pass or a matching failure type. For the mechanism, locate the fractional-pow domain guard in SundialsSolverStandalone and print the base with %.17g or check signbit to separate -0.0 from genuine negative drift. Done when BIOMD0000001065 passing or failing with SOLVER_FAILURE is green, while a different failure type still turns the nightly red.
由索引模型根据 Issue 内容生成。
描述
Summary
BIOMD0000001065 (von Dassow 2000 segment polarity, 148 species) flaps between PASSED and
FAILED (SOLVER_FAILURE). It failed on essentially every nightly from 2026-06-09 to 2026-08-17,
passed once in run 32094317081
(2026-08-18 03:07 UTC), and has failed on every run since.
That single pass was baselined by 52cf62cbc3, which is why the nightly has been red ever since —
full forensics in #2000. This issue is about the model and the mechanism, not that incident.
Is there already a way to mark a flapping test? Half of it exists.
OmexTestCase.Status is a closed enum with exactly three values
(vcell-core/.../sedml/testsupport/OmexTestCase.java:5):
public enum Status { PASS, FAIL, SKIP }
The failure-signature check already exists and works. In OmexTestReport the comparison is not
just pass/fail — for a case documented FAIL, a run that also fails is a change only if the
failure type differs:
} else if (matchingTestCase.known_status == OmexTestCase.Status.FAIL) {
if (matchingTestCase.known_failure_type == null
|| !matchingTestCase.known_failure_type.equals(execSummary.failure_type)) {
// ... recorded as a change
So known_failure_type is exactly the "confirm it failed the way we expect" mechanism. Note also
that known_failure_desc is stored but not compared — correct, since it embeds a per-run temp
path (/tmp/VCell_CLI_<random>/…) and would otherwise differ every night.
What does not exist is a status that tolerates either outcome. Today both directions are
regressions:
| baseline | run passes | run fails |
|---|---|---|
PASS |
green | red |
FAIL + type |
red | green if the failure type matches |
SKIP |
red | red (recorded, stays SKIP) |
So for a genuinely intermittent model there is no setting that is green both ways.
Why the obvious workarounds are not good enough
- Restore
FAIL/SOLVER_FAILURE(the state it held for two months) — correct today and the
right immediate action, but the gate goes red again the next time it passes: "Test case marked
as FAIL … but passed". A stopgap that is guaranteed to flap. - Mark it
SKIP— silences it, butSKIPmeans not run at all (the model list is also
hard-coded inNightlyBMDB_CLI.yml, thecase $number in 235|255|…block). Total coverage loss:
we would never learn that it started passing reliably, and never notice if it began failing in a
new way, which is precisely the signal worth keeping.
Proposed: a fourth status
public enum Status { PASS, FAIL, SKIP, INTERMITTENT }
with the semantics "either outcome is acceptable, but a failure must look like the documented
one":
| run result | INTERMITTENT verdict |
|---|---|
| passes | accepted — no change |
fails with known_failure_type |
accepted — no change |
| fails with a different failure type | change → red |
That keeps the model executing and keeps the failure-signature check, while not gating on the coin
flip. It is a small change — one enum value plus a branch in OmexTestReport, alongside the
existing FAIL branch that already does the type comparison.
The mechanism generalises beyond this model; splitting it into its own issue is reasonable if it
grows.
The actual question about this model
Marking it intermittent manages the symptom. Why it is intermittent is the interesting part, and
#2000 has narrowed it considerably:
- The generated
MathDescriptionis byte-identical across the shas either side of the flip
(verified, with a negative control) — no VCell model-processing change is involved. - The solver binary is unchanged (
v0.0.44-dev4, asset last uploaded 2024-02-11). - The corpus is unchanged (and now pinned by #2003).
The failure is a Hill term raising a species to a fractional power as it passes through zero:
pow(u,v) and u=-0.000000<0 and v=2.619640 not an integer
where: EN_0_0 = -0.000000
Two candidate explanations, with different fixes:
- The guard is wrong. If
EN_0_0is true IEEE-0.0, then-0.0 < 0is false and C99
§F.9.4.4 givespow(-0.0, 2.61964) = +0.0. The C++ guard inSundialsSolverStandalonewould be
rejecting a legal input — and this becomes an instance of #1646, currently markedDoneon the
board. If so, fixing it may make this model pass reliably, which would be the real fix and
would explain the intermittency as "sometimes the drift lands exactly on-0.0, sometimes a
hair below". - It is drift, and the model is simply marginal. A stiff 148-species model whose integrator
undershoots zero into a fractional power will hit this eventually; whether it does depends on
last-ulp differences, which vary with the runner's CPU (glibcpowdispatches differently with
and without FMA). Then the question is whether VCell should clamp a negative concentration to
zero before a fractionalpow— a modelling decision, not just a guard fix.
Distinguishing them is cheap: print the base with %.17g, or test signbit, at the guard.
Suggested work
- Settle (1) vs (2) — one print statement in the solver's domain guard.
- Restore
1065toFAIL/SOLVER_FAILUREso the nightly is honest in the meantime (#2000). - Add
INTERMITTENT, and apply it here. - If it turns out to be (1), fix the guard and check whether this model — and any others using
fractional powers of concentrations — become reliable.
Worth grepping the corpus for other models with fractional exponents on species; if the guard is
wrong, 1065 is unlikely to be the only one sitting near the edge.
Refs #2000, #1646, #1901
- 主要语言
- Java
- 星标
- 140
- 派生
- 35
- 平均合并
- 22 小时 6 分钟
- 30 天内合并 PR
- 14
环境准备
- 提供 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
virtualcell/vcell 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 72/100
virtualcell/vcell#2193 · 1 条评论 ·
维护者通常 1 天内回复
-
Accessibility Requirement Java-based User Interface
难度 2/5 1-3 小时 新手友好度 74/100
virtualcell/vcell#2138 ·
维护者通常 1 天内回复
-
Accessibility Requirement Java-based
难度 2/5 1-3 小时 新手友好度 80/100
virtualcell/vcell#2137 ·
维护者通常 1 天内回复
-
Accessibility Requirement User Interface
难度 2/5 1-3 小时 新手友好度 88/100
virtualcell/vcell#2135 ·
维护者通常 1 天内回复
-
Accessibility Requirement Java-based User Interface
难度 2/5 1-3 小时 新手友好度 84/100
virtualcell/vcell#2134 ·
维护者通常 1 天内回复
查看 virtualcell/vcell 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 77/100
NationalSecurityAgency/ghidra#10149 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 90/100
yegor256/antlr2ebnf-maven-plugin#155 ·
维护者通常 1 天内回复
-
account bug exercise lecture programming user interface
难度 2/5 1-3 小时 新手友好度 72/100
ls1intum/Artemis#14512 · 1 条评论 ·
维护者通常 1 天内回复
-
kind:bug priority:major
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
swiftlang/swift-java#955 ·
维护者通常 1 天内回复