Repository navigation
Conversation
The reference screen took the worst-covered turbine in the pool as the whole campaign's data budget, so one turbine's outage switched screening off for every reference. It now applies screen_min_campaign_days candidate by candidate: a candidate with too little upgraded data is held out of the screen rather than standing it down for the rest, and the screen declines entirely only when no candidate holds enough. That exposed a second inconsistency. A screening estimate already runs with the held-out candidates demoted to their operating-state booleans, because _reference_input puts any candidate outside the pool it is handed among the wake contributors. The campaign's own estimate and its reference report did not -- they kept those candidates as full power references, so the screen ruled on a pool the campaign never used. All three now read the same pool through ScreenResult.power_free, and reference_stability.csv gains an `unjudged` column so a held-out reference stays distinguishable from a ruled-out one. A power-free reference also said only one thing: active power at or above 5% of rated. That conflates a turbine which is out of service with one which is merely becalmed, and the mix of those two states moves across a changeover, so the same boolean means different things on either side of it. It now says two things -- `waking` (is it making a wake, from active power) and `normal_operation` (was it able to run, from the availability counter). normal_operation_feature defaults on. It does not detect curtailment: a turbine held at zero while available reads as operating normally. Recorded benchmark baselines will move: any run with power-free references or wake contributors now carries an extra feature per such turbine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The shift probe slides one prepost placebo's changeover across a calendar year, so every arm is the same campaign meeting different weather, with nothing injected and a truth of 0. Each arm carries five measures of its own shift, and the driver fits the dose-response of reading against shift. It also reads the whole farm the way a campaign report does, one test turbine with every other turbine estimated against the rest, so a run returns twenty readings whose truth is 0 rather than one. The placebo declaration now takes explicit baseline and campaign lengths, and the composed method list can turn the reference screen and the per-reference uplift report off, so every arm of a study holds the same reference pool and pays for only the fits it scores. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The disguise probe cuts a window into alternating day blocks and reads it two ways: the toggle leg takes the record as it stands with the odd blocks toggled on, the prepost leg takes it with every timestamp remapped, SCADA and reanalysis together, so the even blocks become a contiguous pre period and the odd blocks a contiguous post period. Both legs therefore contrast the same two halves of the same rows, and over the default two-year window the halves hold the same number of records of every calendar month. Nothing is injected, so every turbine's truth is 0 and a prepost reading away from 0 belongs to the prepost path. Every step that reads the whole timeline at once is settled once on the undisguised record and handed to both legs: the reanalysis lag match, and northing discovery, whose changepoint search meets different steps when the days are interleaved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The campaign-proximity weighting tilts the baseline toward the changeover, which a prepost fit reads as uplift: on a record whose truth is 0 it moved the reading by +0.154 pp. It is now off by default; a caller can still set an adaptive or a fixed half-life. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CF19 prices the campaign-proximity weighting on a record that must read 0. CF20 ablates the reference power minimum and the reanalysis features and finds neither is the source of the prepost bias. CF21 balances the two periods month for month and two thirds of the bias goes with them, the large per-turbine offsets included. R8 keeps the failure mode the weighting was there for: a very long baseline should not be able to dominate the fit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Scratch scripts live beside the private v1 notes; ruff skips them through gitignore and mypy needs telling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ecision Design for gating the prepost reversal correction with a computed shrinkage lambda instead of a hand-fit fade curve: log-space bias subtraction, an MSE-optimal lambda from forward/reverse uncertainties with a James-Stein positive-part bias term, a low/high effort lever for how sigma is estimated, and an enabled-but-not-yet-P95 headline band. Force-added past the usual specs/ gitignore at the user's request; may be removed from tracking later. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
headline_estimator="reversal" on PowerModelMethod also fits the reverse direction (train the upgraded rows, predict the baseline rows) and reports sqrt((1+r_fwd)/(1+r_rev))-1, cancelling a shrinkage common to both directions. Default stays "forward"; toggle is unaffected. This is the UNGUARDED form: the full correction is applied at every post-period length. The synthetic sweep showed it helps at >=6 months and harms below (over-correcting on a data-starved reverse fit). The design that gates it with a computed, precision-weighted shrinkage lambda is specified in docs/superpowers/specs/2026-09-17-reversal-shrinkage-design.md (commit 505839d); this commit is the foundation that spec's build order extends. Do not use "reversal" on short campaigns until that lambda lands. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
north_scada now requires a layout. source_northed_scada and source_record take one and the probe passes the placebo campaign's own. The campaign findings from this branch were renumbered CF22-CF24 on rebase, so the time-decay reference in issues_campaigns.md moves with them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…machine sync) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A campaign may now be declared with a per-turbine works table and exclusions instead of one changeover and analysis period. wind-up then chooses each upgraded turbine's analysis span and its nearest-K power references (src/wind_up/analysis_period.py), runs each turbine over its own span, and writes the plans into the report. - CampaignSpec / SyntheticCampaign carry works windows and exclusions; analysis_period is optional, or per turbine - the loader reads a works table, exclusions and the Greenbyte schema - generate_dataset injects each turbine from its own changeover - power_model refills a screened pool from reserves, reads each reference against its own pool, and keeps waking booleans over a reference's exclusions (exclusion_channels) - the real Hill of Towie AeroUp T13 campaign is written from open data (benchmarking/campaigns/real.py) Flat declarations take the same path as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
benchmarking/campaigns/rollout.py draws realistic prepost campaigns on Hill of Towie, Penmanshiel and Kelmarsh: a trial from design_campaign (1 to max-1 test turbines), its works scheduled on England and Wales working days by one or two teams, and optionally a full rollout of every other turbine 6-9 months later. The AeroUp Cp shape is injected, scaled by a multiplier, from each worked turbine's own works end, and the data is cut a chosen number of months after the last trial works. Works become a Zenodo-shaped works table, so the period selector chooses each span as for a real campaign. - SyntheticCampaign.other_upgraded: turbines injected but not analysed - real.py: module-level default dates (fixes the B008 lint failure) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bank holidays follow the Scottish rules: 1 and 2 January, Good Friday, the first and last Mondays of May, the first Monday of August, St Andrew's Day and Christmas, with weekend substitutes. Easter Monday and the last Monday of August are working days. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Crews may come from either side of the border, so a working day avoids the bank holidays of Scotland and of England and Wales: Easter Monday and the last Monday of August join the Scottish set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
benchmarking/baselines/study_prepost_campaign_matrix.py runs shipped wind-up over the real HoT T13 campaign and synthetic trial-then-rollout campaigns on Hill of Towie, Penmanshiel and Kelmarsh, one cell per (campaign, multiplier, K, post length), plus an exclusion-channel A/B arm at K=4. It is one resumable invocation on a spawn process pool: cells that are ok are skipped, failed and interrupted ones rerun, and a cell never raises. The cells are merged into a candidate baseline (test and farm bias/spread/score, the line fit across multipliers, reference mean/median/sd/worst_abs/n, real T13 rows) with a leak check, and compared with the committed baseline. - the matrix's period selector takes each cell's K and a 14-day shortest side, so every post length is analysed - north_scada can write the discovered table without its plots; the runner and estimate_campaign pass that through, and the runner takes plan settings - psutil joins the dev group, for each cell's peak RSS Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The prepost campaign matrix now fetches what it needs: Hill of Towie year zips as before, and Kelmarsh and Penmanshiel SCADA from their Zenodo records (ensure_greenbyte_data, size-checked, no network once complete). A new `download` command fetches everything up front; `run` does the same before its first cell. Locations come from the environment or a git-ignored .env at the repo root (benchmarking/env.py, template in .env.example): the Zenodo data directory, the output directory and the reanalysis cache. The shell wins over the file. - download_zenodo_data takes a per-record metadata filename, so two records can share a directory; zenodo_record_files returns a record's file list - python-dotenv joins the dev group Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Open data now lands in <data root>/zenodo/<record id>/ -- 20204946 for Hill of Towie, 5841834 for Kelmarsh, 5946808 for Penmanshiel -- so records never share a directory and their files cannot collide. Each directory keeps its own record metadata, so the per-record metadata filename is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
<data root>/<record id>/, with no zenodo/ level in between. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A leftover folder such as wind_up/plots/__pycache__ from before the src rename was found as a namespace package and failed the build with "package directory src/wind_up/plots does not exist". The wheel's contents are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its data files are byte-identical to 20204946 (v2.0.0); v2.1.0 updates the README and adds a changelog, a data dictionary and a photo. The CI cache key follows the record id, so CI builds a fresh cache in the per-record layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ummary The full matrix needs about 530 CPU-hours, too long for 16 workers. A study now runs at a size: small, a laptop smoke test of every arm, or big, projected at about 11.5 h on 16 workers. A plan command projects a size's hours and memory from measured cell costs, and cells run most expensive first. Each study keeps its records and merged results in one directory to download, while the sources and per-cell working files stay in a __detail sibling. Failed cells are kept on resuming unless --retry-failed, and each size has its own committed baseline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pool rule only ranked spans, and length ranked above the reference count, so when no span met the pool rule the selector took the longest span even with a single reference. A chosen span now needs PlanSettings.min_references (3 by default), and a turbine with no such span raises instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Step 7 keeps one before period: all data up to the cap, every record weighted equally. Step 8 now states its purpose, deciding from the timeline alone which turbines may serve as power references and in what order, and leaves the testing of them to the screen in step 9. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Step 9 gains a first pass that applies step 11's record selection to each test-candidate pair alone and reports the usable hours in each period and the power correlation, dropping a candidate that falls well short of the others on either. This catches a reference downwind of the test turbine in the prevailing wind, which the changed-upwind rule would otherwise strip of most of its records, and with them every other reference's. The measurement screen then runs on the survivors. Replacement is always the nearest reserve. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… steps 7 and 8) Every campaign now goes through the period selector: a declared span is used as given and the candidates are still ranked by distance, with the nearest four as power references and the rest as reserves. A shared changeover is a works window of no length at the changeover, a toggle campaign's at the start of toggling. The flat path, which took every declared reference as a power reference, is gone with CampaignSpec.uses_plans and context_for. An analysis plan exposes its before and after periods, which the run treats over. Part B of the report is laid out by step: 07_periods holds periods.csv and each turbine's timeline, 08_candidates holds candidates.csv with each other turbine's rank, role and reason, 09_screen holds the reference stability table and 15_uplift_distributions the conditional uplift. The step 4 possible yaw-alignment changes are reported as a warning against a turbine whose periods or span they fall inside. The timeline shades the before period blue and the after period orange. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…r it (method step 9 pass 1) - Record selection (step 11 i and iii) shared by the estimate and the data screen: a record is lost when any power reference is invalid, or a turbine upwind of the subject or a reference counts as changed at that time. - A changed turbine counts as changed over the whole span when its works are within 6 months of the test turbine's changeover, otherwise only on the far side of its works. - The data screen drops a candidate reference with too few usable hours or too low a power correlation, and writes reference_data.csv, reference_hours.csv and five plots per test turbine. - Optional plots for each reference measurement (--reference-plots), one folder per reference per test turbine. - Plot fixes: operating relationships coloured by date only, capacity factor under power factor, ERA5 histograms over the full range, dashed rings in the map legends and the span on the map. - docs/analysis-period.md becomes analysis-period-and-reference-selection.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d tidy the measurement plots - Run-level coverage, timeline, power factor, reactive power and northing plots draw the test turbine and its power references only; reactive vs active power shares its axes. - Reactive vs active power joins the operating relationships; the operating-state grids put the plots against wind speed on the left and against power on the right. - A reference measurement skips the step 1, 2 and 4 plots the test turbine's run already has. - Feature importance and the feature overview on a log scale; the residual plots are removed. - The actual vs counterfactual energy is weekly, with each week's uplift below. - Histogram bins span every value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Step 9 states the after-data gate, the unjudged candidates, that pass 2 is prepost only and that the screen's own measurements are what is reported. Step 11 gains an hours-based data floor and reports the configuration losses. Step 12 option B is not pursued. Step 13 option B says where its precision comes from and that option A is its lambda = 0 limit. Steps 10 and 14 promise an uncertainty for the headline and each bin. Step 15 describes the matched two-direction per-bin estimator and bars every subject-turbine signal as a bin variable. The validation section orders the options one at a time. estimating-uplift.md is replaced by method.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… pool The screen measures each candidate against the other candidates (method step 9), so the reference-stability table now reports that measurement rather than a second one against the reference's own nearest neighbours. The reading pools leave the plan, the context and the data screen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e prepost matrix alike prepare_data labels the operating states, aligns the reanalysis, norths the farm over the whole record, finds the possible yaw-alignment changes and adds the waking columns, writing each step's outputs when asked. The composed run calls it in place of its inline steps. The prepost matrix's synthetic and real cells now run it too, with tables but no plots, so the method is judged on the same prepared data in the benchmark as in a real run; the synthetic Hill of Towie site gets its site operating-state labels. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… configurations, toggle pairing, invariant uplift axes Part C of the method now follows docs/v1/method.md's defaults. A measurement needs 24 usable hours in each period. Records are dropped when the subject's or a reference's waking scenario is unknown or names a part waking turbine (the per-turbine part of step 11 ii, which the data screen applies too), when the waking configuration of the subject and its references together has under 24 hours in either period, and in a toggle test when no usable record of the other state lies within one toggle cycle. The hours lost to each rule in each period are written as record_losses.csv. The uplift distributions are binned by upgrade-invariant variables only: the counterfactual power prediction and the aligned ERA5 100 m wind speed. The subject turbine's own wind speed and turbulence are no longer condition axes of the power model, and a bin needs 8 matched hours a side. The farm table carries the combined reference uplift before and after the screen (step 16). The toggle pairing filter moves to the shared toggle module. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… spread method.md now says how the screen counts a candidate's 150 days, that the headline's uncertainty waits on step 14, which part of the waking configuration rule the data screen applies and how a toggle test's periods and pre-toggle records are treated, that the toggle pairing limit is one cycle, that whole-day trimming belongs to option B, how reproducible the model is across machines, that predictions are clipped, how the step 15 matching cells are formed and balanced, the 8-hour bin floor, how filled bins are set and held, the default condition axes, and that the reference spread is the largest minus the smallest. The farm table gains that spread. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…otstrap of the after period The model is fixed and the after period's (actual, counterfactual) records are resampled in circular wall-clock blocks, 24 hours by default, with the sigma also recorded at 6 hours, 1 day, 7 days and 28 days so a study can pick the block length by coverage. The sigma is the headline's sigma_overall, reaches per_turbine.csv, every reference reading (through the screen passes when a reading is reused) and reference_stability.csv, and each measurement folder's uncertainty.csv. The prepost matrix records it for test turbines and references and its metrics gain the one-sigma coverage, z spread and median sigma of each, test turbines against truth and references against zero. It is the sampling component only (method step 14); bias is not in it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…5 wind speed, and score the bins in the matrix The step 15 bins are bootstrapped over their matched records with the two direction models fixed and the bin labels frozen, so sigma_uplift never moves a bin; a filled bin has none. The matrix joins the aligned ERA5 100 m wind speed onto the synthetic truth rows, so the era5_ws axis has a per-bin truth, records every test turbine's bins with estimate, truth and sigma, and adds a bins table of per-bin error and coverage metrics. method.md step 14 now describes the sampling component and names the systematic one as unspecified, and validation gains the coverage target. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…the HPC run Every synthetic matrix cell failed in scoring since the headline sigma landed: the uncertainty row carried a sigma column the harness owns. The row now leaves it to sigma_overall. The matrix also records, per cell, the reverse direction beside the forward headline (scored as the full reversal, step 13 option B at lambda 1), the combined reference uplift before and after the screen, each test turbine's hours lost per reason and its data screen. A test turbine that cannot be measured is reported as not analysed rather than stopping the campaign, and a failed uplift distribution no longer takes the headline with it. method.md wording follows the code where the audit found the code right. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ements out of the test turbine's works A candidate held out of the screen for want of after-period data now leaves the pool for the wake contributors and the nearest reserve takes its place, as method step 9 says of a dropped candidate. The campaign context carries the test turbine's works window, and a reference measured as the subject uses no record inside it, so its before period ends where the test turbine's does. Finding CF30 records the steps 1 to 15 work, the headline sigma, the matrix fix and the laptop dry runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under a shared changeover a test turbine can declare works besides its upgrade. Its periods were planned around the upgrade alone, so another of its changes could fall inside them. Its own data extent is now cut at the nearest such works on either side, as method step 7 says; a declared span is used as given, with a warning naming the works inside it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rsions, waking columns, features and step 15's edge cases Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… validation targets It reads the cell records, so it runs on a partial study, and writes one table per target beside the study with a markdown summary: the combined reference uplift and placebos against zero, the line of measured against true uplift, the error by after-period length, references and season, the sigma's coverage, forward against full reversal and the reversal spec's computed lambda, and two of the open questions (the waking configuration rule's cost, the data screen's measures). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lity, and label power-limited records The loader corrects a zero availability while the turbine produces, labels records power limited from the status log's power-reduction events or pitch above a per-farm limit, and the matrix reads these labels. Kelmarsh now starts on 2016-12-01, after its 2016 power cap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t the 95th percentile Rated power had one bin spanning roughly 12.5 to 27 m/s; against wind speed the top decile is now two 5 % bins. The power axis keeps its ten deciles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ower reaches it A reduced setpoint the turbine's power never reaches leaves it on its normal power curve, and these records were labelled curtailment: about 400 h on each of T11 and T18 over 2022-2024, and 12 % of the BM curtailment label farm-wide. A reduced setpoint now labels the record only when the record's power max reaches 90 % of it, or the power max is missing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…real campaign TuneUp changed nine turbines together on 2024-03-14; its SCADA ends with August 2024, when the trial's analysis ended. It runs at L1, L2, L3 and Lmax, all of its data after the changeover, and every other turbine is a candidate reference. The matrix's real campaigns now come from a registry, and the real table has a row per campaign with the combined reference uplift before and after the screen, the share of before-period hours lost to a changed turbine upwind, and the references each screen dropped. A declaration may now give a shared timing.changeover beside a works table, which then holds every turbine's other works. A new wake_unchanged key declares that the change leaves the upgraded turbines' wakes as they were, so the changed-upwind rule does not count them for it; TuneUp sets it, as without it five of its nine turbines could not be measured. The rule now also counts an upgraded turbine's other declared works under a shared changeover, which it missed before. The cell record reads the record losses a run without run folders writes, and C4 in issues_campaigns.md now describes TuneUp as the prepost campaign it was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the 97.5th percentile Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… share the two cell executors' setup plot-cell writes one cell into its own folder laid out as a composed run, with the campaign and farm reports the matrix otherwise skips, and leaves the study's records alone. Real and synthetic cells now share Part A, the methods and the record's diagnostics, and a synthetic campaign report writes the results across turbines to the farm folder as the composed run does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…one value over its records After record selection every record a model uses is usually "normal" for every turbine, so these columns can never be split on. They are dropped before the fit and named on the feature-importance plot; LightGBM already ignored them, so no estimate changes. method.md's validation order gains, at lower priority, a configuration rule minimum below 24 hours. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…importance plot's bottom right Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…'s standard errors by campaign A synthetic site's campaigns are now tiles: tile i's trial starts at frac(i * 0.618) along the days that leave 12 months before and after it, its data starts 12 to 24 months before the trial, and it prefers turbines no earlier tile tested. Hill of Towie's noise-mode T16 and T17 are never test turbines. validate clusters each mean and coverage standard error by campaign and needs five campaigns for a verdict. CF31 records the stopped first big run that prompted both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…T17 again Noise mode now feeds the uplift in every Hill of Towie campaign: the real AeroUp and TuneUp campaigns and the matrix's synthetic tiles. RolloutSite.never_tested goes, so the tiles draw T16 and T17 as test turbines again. CF31 records the change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er setpoint The region-2 taper now fades a Cp change out as power approaches the record's limit, the higher of its start and end setpoints, rather than rated; the changed power is capped there too. ColumnSchema gains an optional power_setpoint role, which Hill of Towie maps; sources without one are unchanged. CF32 records the measurement: noise-mode records had about 10 % too much injected gain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
see C3 in
issues_campaigns.md