Skip to content

Record how plant #576 resolved: check the caller before clamping - #4

Open
dfalster wants to merge 1 commit into
mainfrom
docs/model-robustness-576-resolved
Open

Record how plant #576 resolved: check the caller before clamping#4
dfalster wants to merge 1 commit into
mainfrom
docs/model-robustness-576-resolved

Conversation

@dfalster

Copy link
Copy Markdown
Member

Follow-up to plant #576 / plant#582. The spline worked example in model-robustness.md was written while #576 was open and left the question hanging — "if conductivity really is ~0 out there, clamping is a physical statement… if not, it should fail". It's now answered, and the answer is neither, which is worth recording because the reasoning generalises.

What the entry now says

The failing lookup was the inverse transport curve, asked for the stem potential that would carry a negative sap flux from a collar at the critical potential — a potential wetter than saturation, which does not exist. The spline was right to refuse. The caller was wrong to ask, because it was asking in the hydraulic shut-down state that the feasibility analysis one level up had already rejected.

Clamping would have returned a plausible stem potential for an impossible state — precisely what the table's Never row already warns about. And widening was aimed at the wrong end of the domain: the failure was at the lower bound (ψ = 0, saturation), not past the vulnerability curve.

Two review questions added

  • Is the guard in the right place — is the caller even entitled to ask? A guard added where a failure surfaces can be correct code in the wrong file.
  • If the same state is handled in more than one place, do they agree? #576 was an asymmetry: one gradient method took the zero-gradient branch in shutdown, its sibling didn't, so the edge case was reachable through only one of them.

Two additions to the reporting half

That half of the original entry stands and paid for itself immediately — naming the spline, point, distance outside, domain and calling function turned a four-call-site bisect into one read. From doing it:

  • Name the bracket, not just the point. A failure inside a solve is usually a property of the interval the caller chose, which is invisible from where it's thrown.
  • Don't tighten a NaN comparison while you're in there. u < lo || u > hi is false for NaN by design in some callers; negating it into an in-range test reads like a diagnostic improvement and is really a behaviour change. I made that mistake first — it broke a documented f(NA) -> NA contract — and reverted it.

Docs only; no rule changes, and the decision table is untouched.

The spline worked example asked "clamp or widen?" and left it open. The answer
was neither, and the reason generalises, so the entry now records it: the lookup
was refusing a stem potential wetter than saturation, asked for from the
hydraulic shut-down state that the feasibility analysis one level up had already
rejected. Clamping would have returned a plausible number for an impossible
state -- the failure mode the table's Never row already warns about -- and
widening was aimed at the wrong end of the domain.

Two review questions added from it: is the guard in the right place (a guard
where a failure surfaces can be correct code in the wrong file), and where a
state is handled in two places, do they agree -- the bug was an asymmetry
between two gradient methods, one of which took the zero-gradient branch in
shutdown and the other did not.

Also two additions to the reporting half, which paid for itself: name the
bracket and not just the point, and do not tighten a NaN comparison on the way
past -- `u < lo || u > hi` is false for NaN by design in some callers, so
negating it into an in-range test reads as a diagnostic improvement and is
really a behaviour change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.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