Skip to content

fix(performance): a failed attempt no longer leaks into the BADA3 retry; fuel-burn rejections are retried - #76

Merged
ramondalmau merged 6 commits into
devfrom
fix/performance-retry-isolation
Oct 21, 2026
Merged

ramondalmau merged 6 commits into
devfrom
fix/performance-retry-isolation

Conversation

@ramondalmau

Copy link
Copy Markdown
Collaborator

Bug (audit I10). run() passed the same table to the BADA4 attempt and to the BADA3 retry, and
the altitude fallback did the same. Each attempt writes aircraft_mass, thrust, fuel_flow, ...
into that table before the fuel-burn check. After a rejection on BADA4, the BADA3 retry took
those columns as operator data:

  • operator fuel flow + efficiency: accepted with impossible fuel (55,674 kg vs limit 45,600),
    no fuel-burn check, no bada_version;
  • operator efficiency only: accepted with the rejected BADA4 fuel;
  • no operator data: rejected again (retry reused the BADA4 fuel), so the BADA3 retry never worked.

Fix: each attempt works on its own copy of the table.

Maintainer decision: a fuel-burn rejection goes through the whole fallback chain (BADA3 retry,
then the altitude fallback when the flight has points below FL20) and fails only if every
attempt is rejected. The fuel-burn error is now retryable.

Effect on NEATS_FINAL: none. Fleet before/after on all 4,959 sample flights is bit-identical
(no flight reaches the fuel-burn check).

Checks: full suite 300 passed; 5 new retry tests + 1 altitude-fallback test, all failing on
the previous code; independent review. Docs: run() docstring, input-prioritization.md,
mrv-specification.md, units audit I10 (before/after table, decision, two older quirks noted).

What to look at: src/pyneats/steps/performance/bada_model.py (df.copy(); guardrail error no
longer retryable=False; retryable=False honoured before the BADA3 retries).

ramondalmau and others added 6 commits October 21, 2026 11:40
…etry

run() passes the same preprocessed DataFrame to the first attempt and to
the BADA3 retry, and the altitude fallback does the same for its two
attempts. run_by_bada_version writes aircraft_mass, thrust, fuel_flow and
other columns into it before the fuel-burn guardrail. After a guardrail
rejection on BADA4, the BADA3 retry took those columns as AO data. With
AO fuel flow and engine efficiency, it then saw "fuel flow + efficiency
+ mass provided", skipped BADA and returned the flight without the
guardrail.

Each attempt now works on its own copy of the DataFrame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Also points the rows of the merged docs PR to #75.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…taFrame

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the column leak fixed, a flight rejected by the fuel-burn guardrail
on BADA4 would be computed again with BADA3 and could be accepted with
BADA3 numbers. Before, that retry always failed (it reused the rejected
BADA4 fuel). An impossible total fuel points to bad trajectory or AO
data, not to the BADA version (maintainer decision).

A failure raised with retryable=False now ends the fallback chain: no
BADA3 retry in run() and none inside the altitude fallback. Besides the
guardrail, only "BADA file without MTOW or OEW" and "missing initial
mass" carry that flag; neither occurs with the files and data in use.

Tests: the rejection is final (AO fuel flow + efficiency, no AO data,
efficiency only); a retryable BADA4 failure still retries with BADA3 and
the retry starts clean; same rule inside the altitude fallback. All fail
on the previous code.

Docs: run() docstring, user docs (fallback chain, fuel-burn check note),
units audit I10.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ude fallback

Maintainer decision, replacing the previous commit's "rejection is
final": the fuel-burn guardrail error is now retryable. A rejected
flight is retried with BADA3 (now clean, see the column-leak fix), then
with the altitude fallback (points below FL20 removed), and fails only
if every attempt is rejected.

run() and the altitude fallback keep honouring retryable=False before
their BADA3 retries; on this path only two internal consistency errors
carry that flag (no MTOW/OEW when the take-off mass is estimated, no
initial mass), and neither occurs with the BADA files in use.

Tests: a rejection is retried with BADA3 and accepted when BADA3 is
plausible (no AO data, AO efficiency only); with impossible AO fuel the
altitude fallback runs. All fail on the code before the fix.

Docs: run() docstring, user docs (fuel-burn check note, fallback chain,
mrv-specification rule 2), units audit I10 with a before/after table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uirks in I10

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ramondalmau
ramondalmau merged commit 53bda5f into dev Oct 21, 2026
6 checks passed
@ramondalmau
ramondalmau deleted the fix/performance-retry-isolation branch October 21, 2026 11:59
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