Operations ========== **Implementation status:** Partial (coverage matrix row *Operations* — LF wired per DL-010/017; additive ARM/FAO/ATM present; per-route resolution absent from the production wedge). The page's printed forms — three **separate** linear efficiency ramps, the multiplicative :math:`e^* = (1-\Delta\eta)\,e_{in}`, and the eq. 5 RPTK flight-count recomputation — are implemented standalone in ``src/engine/operations-full.ts`` (DL-137, Stage-1 shadow; the three end-values are named in the RST but never valued anywhere in the corpus, so they are required caller arguments). The production wedge remains subtractive on an S-curve with a fixed 0.35/0.35/0.30 split — a documented divergence from the printed linear ramps. **Source:** ``src/engine/cascade.ts:computeLCA`` (ops wedge, ``lfAt``, ``lfFactorAt``), ``src/engine/constants.ts:OPS_AMBITION``, ``src/engine/operations-full.ts`` **Test evidence:** ``tests/load-factor.spec.ts``, ``tests/suite-m-operations-fuelburn.spec.ts`` Efficiency levers: ARM + FAO + ATM ---------------------------------- Operational fuel-burn improvement is the sum of three categories (cf. CASCADE *Operations*): .. math:: \Delta\eta_{ops} = \Delta\eta_{ARM} + \Delta\eta_{FAO} + \Delta\eta_{ATM} * **ARM** — Aircraft Retrofit & Maintenance (ambition table 0.4–2.0 %) * **FAO** — Fleet & Airport Operations (0.8–4.0 %) * **ATM** — Air Traffic Management (1.0–5.0 %) The scenario may set each component explicitly (``fb_arm``, ``fb_fao``, ``fb_atm``) or a single total ``fb``, which is split by the fixed category shares 35 % / 35 % / 30 % (``OPS_CATEGORIES``). The ops wedge in the time series is :math:`\Delta_{ops} = G_{gross} \cdot (\Delta\eta_{ops}/100) \cdot s(t)`, where :math:`s(t)` is the normalised adoption curve over the model window. Load factor ----------- Raising passenger load factor conserves revenue-passenger traffic, so fewer flights deliver the same payload; energy and emissions scale with the flight count (cf. CASCADE *Operations*, load-factor equations, RPTK conservation; DL-010/DL-017). Freighters are exempt. The aggregate energy multiplier at year :math:`y`: .. math:: F_{LF}(y) = (1 - f_{freight})\,\frac{LF_{in}}{LF(y)} + f_{freight} with :math:`LF_{in}` the baseline load factor (``lf_entry_value``, default 85 % — neutral for the frozen baseline; set 82.6 %, the IATA 2019 global passenger value :cite:`iata_wats`, for CASCADE-reproduction scenarios) and :math:`f_{freight}` the freighter share of fuel burn (``lf_freight_share``, default 10 %, literature range 8–12 %). The load factor itself ramps on an S-curve from ``lf_entry_year`` (default 2024) to 2050: .. math:: LF(y) = LF_{in} + (LF_{target} - LF_{in})\, s\!\left( \frac{y - y_{entry}}{2050 - y_{entry}}\right) The lever enters the ops wedge as :math:`G_{gross}\cdot(1 - F_{LF}(y))` (negative when the target load factor is below baseline — more flights) and applies in both offset modes; it is exactly zero at defaults so the frozen baseline is unaffected. Test evidence (8 tests) pins: neutrality at defaults, frozen-baseline invariance, monotonicity in both directions, the RPTK-conservation identity (wedge = gross × pax share × (1 − LF_in/LF)), freighter exemption, ramp behaviour, and whole-engine conservation. Contrail avoidance ------------------ **Implementation status:** Extended — CASCADE *application* parity. The RST set publishes **no** contrail formulation (verified by full-text grep of the RST set, 2026-07-18); the CASCADE app exposes the strategy with exactly the inputs modelled here **Source:** ``src/engine/contrails.ts`` (pure module — **not** imported by ``cascade.ts``), UI in ``src/components/modals/OperationsModal.tsx`` (Contrails tab) **Test evidence:** ``tests/contrails.spec.ts`` (20 tests) Avoidance ramps from 0 at ``ca_start_year`` (default 2025) to the target share of contrail forcing at ``ca_target_year`` (default 2050), then holds — the same hold-not-stretch convention as the other levers. Any ``CurveShape`` may be selected via ``curve_ca``; the default ``'linear'`` matches the RST default for operations improvements: .. math:: r(y) = s\!\left(\frac{y - y_{start}}{y_{target} - y_{start}}\right) \in [0, 1], \qquad r = 1 \text{ held beyond } y_{target} Prediction-success (knowledge) quality scales effectiveness — ``none / partial / perfect`` = ×0.0 / ×0.6 / ×1.0. These factors are **documented HyFlux fallback assumptions**: the RST set publishes no numeric effectiveness factors for the app's knowledge modes (grep-verified): .. math:: X_{avoided}(y) = \operatorname{clamp}_{[0,1]}\!\Big( \frac{X_{target}}{100}\; r(y)\; k_{knowledge}\Big) Rerouted flights burn ``ca_fuel_penalty`` % more fuel; the fleet-average extra burn is the per-flight penalty times the avoided fraction (conservative — in reality ~10 % of flights cause ~80 % of contrail warming, so the true rerouted share is smaller), and is netted against the avoided forcing as a CO₂ cost (fuel-burn % ≈ CO₂ % for the same fuel): .. math:: \Delta_{net}\ [\text{frac. of fleet CO}_2] = X_{avoided}\cdot R_{CO_2eq} - \frac{X_{avoided}\cdot p_{fuel}}{100}, \qquad R_{CO_2eq} = \tfrac{2}{3} ``CONTRAIL_CO2EQ_RATIO`` (:math:`R_{CO_2eq}`) expresses contrail-cirrus forcing as a fraction of aviation CO₂ forcing, anchored to the ``nonco2.ts`` envelope: Jet-A central ERF multiplier 2.0 ⇒ non-CO₂ ≈ 1.0×CO₂, of which contrail-cirrus is ~2/3 (Lee et al. 2021 ordering :cite:`lee2021`). Conceptual, literature-approximate, editable — same status as ``nonco2.ts``. The net fraction is signed and can go negative when the fuel penalty dominates. Defaults are **lever OFF** (``ca_target_share = 0`` ⇒ all outputs exactly zero), so every existing scenario result is bit-identical. The module is deliberately pure and is not yet wired into the aggregate sweep — a future integration multiplies the net fraction by fleet CO₂ to obtain GtCO₂e; the OperationsModal tab (knowledge picker, start/target years, target share, fuel penalty, curve shape) exposes the parameters and URL-persists them today. Known deviations / limitations ------------------------------ * Per-route operations resolution (fleet-assignment deltas, direct-routing and taxi savings per route) is not modelled; all levers are aggregate. * The contrail lever is an aggregate, display-level quantity: it is not wired into the aggregate sweep, and both the knowledge factors (0 / 0.6 / 1.0) and :math:`R_{CO_2eq} = 2/3` are documented fallback/conceptual assumptions, not CASCADE-published values. * The ambition-table ``AMBITION.ops`` (3–21 %) is treated as ARM+FAO+ATM only; load factor is a separate multiplicative lever. * Curve-shape parameters for the individual ARM/FAO/ATM levers (``curve_arm`` etc.) are URL-persisted but the engine currently applies one shared adoption curve to the summed total. * The custom **pulse curve** (CASCADE *Operations*, Custom Curves → Pulse) is implemented exactly as ``curves.ts:pulseAt`` and documented under :doc:`extensions`; UI exposure remains deferred because the ``CurveEditor`` param model does not map onto the pulse parameter set (see :doc:`aircraft`).