FAILURE MAP
← Case archive

FA-68946 / Tide and marine navigation tables / Open access

Under-keel clearance with squat: Drying heights are added as depth · case 01

Vessels are cleared over banks that dry at low water.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

A negative charted drying height is treated as a positive depth via abs().

VERIFIED REPAIR

Use the signed charted depth so drying heights reduce the water available.

Unsuccessful approach: Subtracting the tide as well as the drying height double-counts the datum shift.

Case contract

Input [charted, tide, draft, speed_kn, cb, confined, margin]. Charted value is depth below chart datum (negative means a drying height above datum). Squat = cb*speed^2/100 metres in open water and twice that when confined. UKC = charted+tide-draft-squat. Required clearance is margin*draft. Return [round(ukc,3), ukc>=required].

Why this case matters

Tide tables and passage plans turn published predictions into go/no-go decisions about depth, clearance and timing.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    d,tide,draft,v,cb,confined,margin=x
    squat=cb*v*v/100
    if confined: squat*=2
    water=abs(d)+tide
    ukc=water-draft-squat
    return [round(ukc,3),ukc>=margin*draft]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2]', [-1.2, 3.8, 1.6, 4, 0.45, False, 0.2], [0.928, True]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, False, 0.1], [2.488, True]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, true, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, True, 0.1], [1.976, True]), ('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1]', [9.0, 2.0, 8.0, 6, 0.82, False, 0.1], [2.705, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1]', [9.0, 2.0, 8.0, 10, 0.82, True, 0.1], [1.36, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True])], [('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1]', [9.0, 2.0, 8.0, 6, 0.82, False, 0.1], [2.705, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1]', [9.0, 2.0, 8.0, 10, 0.82, True, 0.1], [1.36, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, true, 0.05]', [15.0, 0.0, 12.0, 12, 0.7, True, 0.05], [0.984, True]), ('under-keel clearance with squat [4.0, 1.0, 4.3, 0, 0.6, false, 0.1]', [4.0, 1.0, 4.3, 0, 0.6, False, 0.1], [0.7, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True])], [('under-keel clearance with squat [-2.0, 4.5, 1.0, 3, 0.4, false, 0.2]', [-2.0, 4.5, 1.0, 3, 0.4, False, 0.2], [1.464, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, true, 0.05]', [15.0, 0.0, 12.0, 12, 0.7, True, 0.05], [0.984, True]), ('under-keel clearance with squat [4.0, 1.0, 4.3, 0, 0.6, false, 0.1]', [4.0, 1.0, 4.3, 0, 0.6, False, 0.1], [0.7, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True]), ('under-keel clearance with squat [8.0, 1.0, 7.0, 5, 0.75, false, 0.1]', [8.0, 1.0, 7.0, 5, 0.75, False, 0.1], [1.812, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True])], [('under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2]', [-1.2, 3.8, 1.6, 4, 0.45, False, 0.2], [0.928, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True]), ('under-keel clearance with squat [-2.0, 4.5, 1.0, 3, 0.4, false, 0.2]', [-2.0, 4.5, 1.0, 3, 0.4, False, 0.2], [1.464, True]), ('under-keel clearance with squat [8.0, 1.0, 7.0, 5, 0.75, false, 0.1]', [8.0, 1.0, 7.0, 5, 0.75, False, 0.1], [1.812, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True]), ('under-keel clearance with squat [11.0, 0.21, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.21, 10.0, 5, 0.8, False, 0.1], [1.01, True]), ('under-keel clearance with squat [6.0, 0.9, 6.0, 5, 0.8, false, 0.1]', [6.0, 0.9, 6.0, 5, 0.8, False, 0.1], [0.7, True])], [('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True]), ('under-keel clearance with squat [11.0, 0.21, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.21, 10.0, 5, 0.8, False, 0.1], [1.01, True]), ('under-keel clearance with squat [6.0, 0.9, 6.0, 5, 0.8, false, 0.1]', [6.0, 0.9, 6.0, 5, 0.8, False, 0.1], [0.7, True]), ('under-keel clearance with squat [4.0, 1.0, 4.0, 0, 0.7, false, 0.25]', [4.0, 1.0, 4.0, 0, 0.7, False, 0.25], [1.0, True]), ('under-keel clearance with squat [4.0, 0.97, 4.0, 0, 0.7, false, 0.25]', [4.0, 0.97, 4.0, 0, 0.7, False, 0.25], [0.97, False]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, False, 0.1], [2.488, True])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2][3.328, True][0.928, True]Failed
under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1][2.488, True][2.488, True]Passed
under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, true, 0.1][1.976, True][1.976, True]Passed
under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15][1.95, True][0.95, True]Failed
under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1][2.705, True][2.705, True]Passed
under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1][1.36, True][1.36, True]Passed
under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1][1.992, True][1.992, True]Passed

SHA-256 / db31357ab42feb038ab385bd233f02988ca1fffafb047550e521c2b12509641c

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    d,tide,draft,v,cb,confined,margin=x
    squat=cb*v*v/100
    if confined: squat*=2
    water=d+tide if d>=0 else d-tide
    ukc=water-draft-squat
    return [round(ukc,3),ukc>=margin*draft]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2]', [-1.2, 3.8, 1.6, 4, 0.45, False, 0.2], [0.928, True]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, False, 0.1], [2.488, True]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, true, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, True, 0.1], [1.976, True]), ('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1]', [9.0, 2.0, 8.0, 6, 0.82, False, 0.1], [2.705, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1]', [9.0, 2.0, 8.0, 10, 0.82, True, 0.1], [1.36, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True])], [('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1]', [9.0, 2.0, 8.0, 6, 0.82, False, 0.1], [2.705, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1]', [9.0, 2.0, 8.0, 10, 0.82, True, 0.1], [1.36, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, true, 0.05]', [15.0, 0.0, 12.0, 12, 0.7, True, 0.05], [0.984, True]), ('under-keel clearance with squat [4.0, 1.0, 4.3, 0, 0.6, false, 0.1]', [4.0, 1.0, 4.3, 0, 0.6, False, 0.1], [0.7, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True])], [('under-keel clearance with squat [-2.0, 4.5, 1.0, 3, 0.4, false, 0.2]', [-2.0, 4.5, 1.0, 3, 0.4, False, 0.2], [1.464, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, true, 0.05]', [15.0, 0.0, 12.0, 12, 0.7, True, 0.05], [0.984, True]), ('under-keel clearance with squat [4.0, 1.0, 4.3, 0, 0.6, false, 0.1]', [4.0, 1.0, 4.3, 0, 0.6, False, 0.1], [0.7, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True]), ('under-keel clearance with squat [8.0, 1.0, 7.0, 5, 0.75, false, 0.1]', [8.0, 1.0, 7.0, 5, 0.75, False, 0.1], [1.812, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True])], [('under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2]', [-1.2, 3.8, 1.6, 4, 0.45, False, 0.2], [0.928, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True]), ('under-keel clearance with squat [-2.0, 4.5, 1.0, 3, 0.4, false, 0.2]', [-2.0, 4.5, 1.0, 3, 0.4, False, 0.2], [1.464, True]), ('under-keel clearance with squat [8.0, 1.0, 7.0, 5, 0.75, false, 0.1]', [8.0, 1.0, 7.0, 5, 0.75, False, 0.1], [1.812, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True]), ('under-keel clearance with squat [11.0, 0.21, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.21, 10.0, 5, 0.8, False, 0.1], [1.01, True]), ('under-keel clearance with squat [6.0, 0.9, 6.0, 5, 0.8, false, 0.1]', [6.0, 0.9, 6.0, 5, 0.8, False, 0.1], [0.7, True])], [('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True]), ('under-keel clearance with squat [11.0, 0.21, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.21, 10.0, 5, 0.8, False, 0.1], [1.01, True]), ('under-keel clearance with squat [6.0, 0.9, 6.0, 5, 0.8, false, 0.1]', [6.0, 0.9, 6.0, 5, 0.8, False, 0.1], [0.7, True]), ('under-keel clearance with squat [4.0, 1.0, 4.0, 0, 0.7, false, 0.25]', [4.0, 1.0, 4.0, 0, 0.7, False, 0.25], [1.0, True]), ('under-keel clearance with squat [4.0, 0.97, 4.0, 0, 0.7, false, 0.25]', [4.0, 0.97, 4.0, 0, 0.7, False, 0.25], [0.97, False]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, False, 0.1], [2.488, True])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2][-6.672, False][0.928, True]Failed
under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1][2.488, True][2.488, True]Passed
under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, true, 0.1][1.976, True][1.976, True]Passed
under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15][-4.85, False][0.95, True]Failed
under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1][2.705, True][2.705, True]Passed
under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1][1.36, True][1.36, True]Passed
under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1][1.992, True][1.992, True]Passed

SHA-256 / 31e8b2093c2e9b33d4dfd2649354a9323c8d17c7b940948f78e17fd5682b425c

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    d,tide,draft,v,cb,confined,margin=x
    squat=cb*v*v/100
    if confined: squat*=2
    water=d+tide
    ukc=water-draft-squat
    return [round(ukc,3),ukc>=margin*draft]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2]', [-1.2, 3.8, 1.6, 4, 0.45, False, 0.2], [0.928, True]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, False, 0.1], [2.488, True]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, true, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, True, 0.1], [1.976, True]), ('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1]', [9.0, 2.0, 8.0, 6, 0.82, False, 0.1], [2.705, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1]', [9.0, 2.0, 8.0, 10, 0.82, True, 0.1], [1.36, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True])], [('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1]', [9.0, 2.0, 8.0, 6, 0.82, False, 0.1], [2.705, True]), ('under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1]', [9.0, 2.0, 8.0, 10, 0.82, True, 0.1], [1.36, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, true, 0.05]', [15.0, 0.0, 12.0, 12, 0.7, True, 0.05], [0.984, True]), ('under-keel clearance with squat [4.0, 1.0, 4.3, 0, 0.6, false, 0.1]', [4.0, 1.0, 4.3, 0, 0.6, False, 0.1], [0.7, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True])], [('under-keel clearance with squat [-2.0, 4.5, 1.0, 3, 0.4, false, 0.2]', [-2.0, 4.5, 1.0, 3, 0.4, False, 0.2], [1.464, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1]', [15.0, 0.0, 12.0, 12, 0.7, False, 0.1], [1.992, True]), ('under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, true, 0.05]', [15.0, 0.0, 12.0, 12, 0.7, True, 0.05], [0.984, True]), ('under-keel clearance with squat [4.0, 1.0, 4.3, 0, 0.6, false, 0.1]', [4.0, 1.0, 4.3, 0, 0.6, False, 0.1], [0.7, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True]), ('under-keel clearance with squat [8.0, 1.0, 7.0, 5, 0.75, false, 0.1]', [8.0, 1.0, 7.0, 5, 0.75, False, 0.1], [1.812, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True])], [('under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2]', [-1.2, 3.8, 1.6, 4, 0.45, False, 0.2], [0.928, True]), ('under-keel clearance with squat [5.0, 1.0, 5.0, 7, 0.5, false, 0.0]', [5.0, 1.0, 5.0, 7, 0.5, False, 0.0], [0.755, True]), ('under-keel clearance with squat [-2.0, 4.5, 1.0, 3, 0.4, false, 0.2]', [-2.0, 4.5, 1.0, 3, 0.4, False, 0.2], [1.464, True]), ('under-keel clearance with squat [8.0, 1.0, 7.0, 5, 0.75, false, 0.1]', [8.0, 1.0, 7.0, 5, 0.75, False, 0.1], [1.812, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True]), ('under-keel clearance with squat [11.0, 0.21, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.21, 10.0, 5, 0.8, False, 0.1], [1.01, True]), ('under-keel clearance with squat [6.0, 0.9, 6.0, 5, 0.8, false, 0.1]', [6.0, 0.9, 6.0, 5, 0.8, False, 0.1], [0.7, True])], [('under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15]', [-0.5, 2.9, 1.2, 5, 0.5, True, 0.15], [0.95, True]), ('under-keel clearance with squat [11.0, 0.3, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.3, 10.0, 5, 0.8, False, 0.1], [1.1, True]), ('under-keel clearance with squat [11.0, 0.21, 10.0, 5, 0.8, false, 0.1]', [11.0, 0.21, 10.0, 5, 0.8, False, 0.1], [1.01, True]), ('under-keel clearance with squat [6.0, 0.9, 6.0, 5, 0.8, false, 0.1]', [6.0, 0.9, 6.0, 5, 0.8, False, 0.1], [0.7, True]), ('under-keel clearance with squat [4.0, 1.0, 4.0, 0, 0.7, false, 0.25]', [4.0, 1.0, 4.0, 0, 0.7, False, 0.25], [1.0, True]), ('under-keel clearance with squat [4.0, 0.97, 4.0, 0, 0.7, false, 0.25]', [4.0, 0.97, 4.0, 0, 0.7, False, 0.25], [0.97, False]), ('under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1]', [12.0, 1.5, 10.5, 8, 0.8, False, 0.1], [2.488, True])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
under-keel clearance with squat [-1.2, 3.8, 1.6, 4, 0.45, false, 0.2][0.928, True][0.928, True]Passed
under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, false, 0.1][2.488, True][2.488, True]Passed
under-keel clearance with squat [12.0, 1.5, 10.5, 8, 0.8, true, 0.1][1.976, True][1.976, True]Passed
under-keel clearance with squat [-0.5, 2.9, 1.2, 5, 0.5, true, 0.15][0.95, True][0.95, True]Passed
under-keel clearance with squat [9.0, 2.0, 8.0, 6, 0.82, false, 0.1][2.705, True][2.705, True]Passed
under-keel clearance with squat [9.0, 2.0, 8.0, 10, 0.82, true, 0.1][1.36, True][1.36, True]Passed
under-keel clearance with squat [15.0, 0.0, 12.0, 12, 0.7, false, 0.1][1.992, True][1.992, True]Passed

SHA-256 / 4f6c0739579fd451f105f4855056cff712dd8abb72629bcc73a30cf81a03ff26

Verification & scope

A deterministic toy model with stipulated rules and constants; not certified hydrographic software or a substitute for official tide tables. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:48:06.898210+00:00.

Case digest / ba2425289b89e7af2f3523bac555f6fbdfa2779dc2d669802e87ebcf53ddf9fe