Part 2 of 2
Drift Prediction on a Critical Fan Motor
- 0 new sensors
- 463 automated assertions
- 3 findings from unread telemetry
- runs entirely local
Overview
What it is
A condition-monitoring tool for critical exhaust fans, built on their existing meter and protection-relay telemetry. No new sensors, no cloud, runs locally.
It learns each fan's own normal operating state from that fan's own data, then compares like-for-like periods across weeks to detect drift toward degradation. It reports a percentage change per component rather than a single blended health score.
It is built on the ingestion pipeline, database and design rules of an earlier piece of work on distribution-board anomaly detection. That half asks did something depart from normal today? This half asks is this fan slowly changing across weeks? Sudden departures and slow drift need different detectors, so the tool has both.
Read Part 1 — Anomaly Detection on Distribution Boards →
What happened when it met real data
Before it could answer the question it was built for, it surfaced three things nobody was looking for:
- Both meters carried the same wiring fault on the same two phases — reporting negative real power for a motor, which is physically impossible.
- One fan's running load stepped down by roughly a fifth on a single date and stayed there, undocumented.
- One fan showed an order-of-magnitude higher standing earth leakage than its identical sibling — a permanent gap, and far below anything protection would trip on.
Two of the three are instrumentation faults that corrupt any downstream energy or billing data drawn from those meters. All three came from telemetry that was already being collected and never read.
Findings are described in generalised terms throughout — ratios and orders of magnitude rather than absolute readings, relative dates, and schematic figures rather than plots of the underlying data. The reasoning that establishes each one as real is in the Findings tab.
What it doesn't claim
It does not say the fan is degrading. It cannot yet — and it says so explicitly rather than guessing.
The metering fault corrupted everything before the repair. Two weeks of trustworthy data have accumulated since, and collection is ongoing. That is enough to show the method does not produce false positives on stable equipment, and not enough to demonstrate that it detects degradation, because no monitored fan has degraded. Roughly six months of running data is the target for real visibility.
When the tool has insufficient trustworthy history it reports that, along with the date from which data can be trusted. It never manufactures a verdict.
The design position
Every output is deterministic arithmetic checked against physical law — no machine learning anywhere in the analysis path. A motor cannot generate power; power factor cannot exceed one; P = V × I × PF must reconcile. Findings anchored to laws rather than to thresholds somebody picked can be defended line by line to the electrician who has to act on them.
Code was written with heavy AI assistance. The analytical decisions were not. That distinction is set out in the Technical tab.
Findings
Three findings from a few weeks of telemetry that was already being collected and never read. Two are instrumentation faults that corrupt any downstream energy or billing data drawn from those meters. One is an undocumented change to a critical asset.
These are described in generalised terms. The assets are anonymised as Fan A and Fan B — two physically identical units on the same installation — magnitudes are given as ratios and orders of magnitude rather than absolute readings, dates are relative, and the figures are schematics of the detection rather than plots of the underlying data. The detection logic is the transferable part, and it survives the generalisation intact.
1. A systematic metering fault on both fans
What the data showed. Two of the three phases reported negative real power for the first stretch of the record, on both fans.
Schematic, not plotted data. The shape is what matters: two channels sitting on the impossible side of zero, and every channel reconciling once the wiring was corrected.
Why it must be an instrument fault. A motor consumes power; it cannot generate it. A negative real power reading on a running motor is not an unusual electrical condition — it is a physically impossible one. The reading is therefore evidence about the meter, not about the fan.
Why it is systematic rather than coincidental. The same fault appeared on the same two phases on two different fans. That pattern points at a commissioning error applied consistently across the installation, not at two independent instrument failures that happened to land identically.
Refining the diagnosis. The tool's first diagnosis was reversed CT polarity. Tested against the data, that does not hold: the power factor magnitude on the affected phases came out at roughly half the healthy phase's value, and a pure sign inversion would have reconciled exactly rather than leaving a factor-of-two discrepancy. The evidence is consistent instead with the current transformer being referenced against the wrong phase's voltage.
Stated as what it is: a strong inference from power factor magnitudes, confirmable by a phasor check at the panel. Not a physical measurement.
Confirmation. Both meters were repaired on consecutive days, partway through the record. After repair the readings reconcile with physics — P = V × I × PF balances to within a couple of percent, where before it could not be made to balance at all.
Impact. All power, power factor and energy data from before the repair is unusable. Anything fed by those meters over that period — energy reporting, load studies, any billing derived from them — was wrong.
Why the data was excluded rather than corrected. The obvious fix is to take magnitudes and move on. We tested that: it undercounts power by roughly a third and gets power factor wrong by a factor of two, because the fault is not a pure inversion. Worse, the negative sign is the only warning that the data is untrustworthy. Stripping it leaves a plausible-looking wrong number, which is a more dangerous object than an obviously broken one. The affected channels were excluded and the current channel — unaffected, because current is unsigned — was retained.
2. A real load change on Fan A
What the data showed. Running current stepped down by roughly a fifth on a single identifiable date, and stayed at the new level thereafter rather than recovering.
Schematic, not plotted data. Like-for-like matters more than the magnitude: the fan also runs extended shifts at a higher load, and comparing across the two duty patterns instead of within one inflates the pre-step level and produces a different, wrong percentage.
Why it is real and not the metering fault. Two independent reasons. Current is unsigned and was unaffected by the wiring fault, so this channel was trustworthy throughout. And the current did not move when the meter was repaired later — if the step had been an artefact of the fault, the repair would have moved it back.
Dating it. The step was located with a one-change-point fit minimising within-segment deviation. An earlier implementation that maximised the gap between segment medians dated the same event to three different days on three channels, because inside a stable run the medians barely move wherever you cut. The corrected fit collapses all three channels onto one date.
Cause: unknown, by design. A setpoint change, a damper adjustment, a belt issue, or a developing fault would all produce this signature. The electrical data cannot distinguish between them. The finding is flagged for cross-check against maintenance records rather than assigned a cause.
A sustained change of that size in the load of a critical fan, with no corresponding record, is worth someone's attention whichever of those it turns out to be.
3. An order-of-magnitude leakage imbalance between identical units
What the data showed. Standing earth leakage current on Fan B sat roughly an order of magnitude above Fan A — the physically identical unit beside it — as a permanent offset rather than an event.
Schematic on a log scale, not plotted data. The gap is permanent, and it sits far below the trip threshold — which is precisely why protection was never going to surface it.
Context on run time. Fan B ran for well under 1% of the record. On a running-only analysis it produced nothing at all. Earth leakage is an insulation property and flows whenever the circuit is energised, so re-framing the analysis around energised time rather than running time is what made this visible.
Why it matters despite being well within limits. The absolute figure is around two orders of magnitude below the relay trip threshold, and in isolation there is no absolute rule that flags it. But an order-of-magnitude difference between two identical units on the same installation is not explicable by normal variation, and elevated standing leakage is a signature of insulation degradation. It justifies an insulation resistance test.
The general principle. Sibling comparison beats absolute thresholds when you have no failure history. An absolute threshold requires knowing what the number should be. A sibling comparison only requires two units that ought to agree — and it gets stronger with every additional asset onboarded.
What these three have in common
None of them was the thing the tool was built to find. It was built to answer whether a fan is degrading, and it has not yet answered that.
All three came out of the work of establishing which channels could be trusted before any detection logic ran — and all three came from sensors that were already installed, already logging, and already being ignored.
Journey
Three builds, and each one was killed by the same thing: real data behaving in a way the previous build had assumed it wouldn't.
Build 1 — trained on synthetic data
The first version learned what normal looked like from data I generated.
It worked on quiet boards. It broke on messy ones — producing sawtooth output that corresponded to nothing in the equipment, and at one point reporting 0% health on a board that was operating entirely normally.
The failure is obvious in hindsight. Synthetic data encodes the assumptions of whoever wrote the generator. Mine was clean, regular, and well-behaved, because that was my mental model of a fan motor. The tool learned my mental model and then met a real building.
What it cost me and what it bought me: the entire baseline approach. Normal had to be learned from the equipment's own real-world state, not from a model of what its state should be.
Build 2 — one number for everything
The second version blended every channel into a single headline figure: 67% probability of failure this week.
It output 50–60% failure probability every week, on healthy equipment, indefinitely.
That figure is impossible on its face, and the impossibility was the useful part. A number that never moves is not a measurement. Worse, when I tried to work out why it sat at 55%, I found I couldn't — the blend had destroyed the information that produced it. I could not tell whether the insulation was the problem, or one phase, or the load.
I had built the thing I would not have trusted if someone had handed it to me.
The correction: the components had to be treated separately. Each channel points at a different part of the system — insulation, a specific phase, mechanical load — and a reader needs to see which one moved. Splitting them also cuts false positives, because a single blended score can be pushed over a threshold by an accumulation of small changes that individually mean nothing.
I have never regretted removing that number. It was the most impressive-looking output the project ever produced and the least honest.
Build 3 — the current one
Baseline learned from the equipment's own real-world state. Data split into event and non-event days. Output changed from a failure threshold to a percentage per component, degrading or improving, compared across weeks.
The event/non-event split was not planned. It came from noticing that some days the fan ran all day and other days only its scheduled window — and that comparing a heavy week against a light week read as degradation when it was nothing but usage. Splitting the comparison by day type collapsed a phantom drift signal to zero.
The assumption that had to die: 24/7 running
The fan was understood to be a continuously running asset, and the early analysis was built on that. It was a reasonable read — there was current on the circuit around the clock, and no reason from the outside to think otherwise.
It was wrong. Current on the circuit is not the same as a running motor.
The hard-coded threshold I had used to separate running from off sat below the fan's actual idle current. So virtually every minute counted as running, and one comparison reported an absurd four-figure percentage change. A phantom, produced entirely by a threshold that looked completely safe when I wrote it.
The fix was to stop hard-coding it. The tool now learns each fan's idle/running split from that fan's own current histogram — on this asset, roughly an order of magnitude above the value I had hard-coded. With that, the real operating pattern resolved: a scheduled window of a few hours in the early morning. Not 24/7 at all.
The same principle then extended further. A second fan barely ran — well under 1% of the record — so on a running-only analysis it produced a blank page. But earth leakage is an insulation property, not a running property: it flows whenever the circuit is energised. I could already see the elevated standing leakage sitting in the raw file myself. Re-engineering the analysis around energised versus running rather than running alone turned that blank page into the most actionable finding in the project.
Challenging the tool's own conclusion
When the tool identified the wiring fault, it labelled the cause "reversed CT polarity". That was a plausible diagnosis and I nearly shipped it.
Instead we tested the claim against the data: if the polarity were simply reversed, would flipping the sign recover the truth? It would not — the power factor magnitude on the affected phases came out at roughly half the healthy phase's value, a factor of two off. A pure inversion would have reconciled exactly.
The diagnosis was corrected to a phase-reference error: the current transformer referenced against the wrong phase's voltage. The practical consequence is that the report now sends an electrician to check the right thing.
I state that inference as an inference. The data is inconsistent with a simple polarity reversal and points at phase assignment; confirming it requires a phasor check at the panel. Calibrated confidence is worth more here than certainty, because if I present a strong inference as a measurement and it's ever disproven in detail, every other finding in the report takes the credibility hit with it.
Lessons
Synthetic data teaches your assumptions back to you. Build 1 was a very effective model of what I believed about fan motors.
A number that never moves is not a measurement. And a blend you can't decompose is worse than the components you built it from.
Everything machine-specific should be learned from the machine. One hard-coded current threshold looked entirely safe and produced a four-figure phantom. Every hard-coded constant is an assumption waiting for a real asset to contradict it.
Domain knowledge drove the design more than the software did. Splitting energised from running came from understanding that leakage is an insulation property. No amount of better statistics would have produced that.
Test your tool's diagnosis, not just its detection. It correctly found a fault and incorrectly named it. Detection and diagnosis fail independently.
Check the raw file by hand. The leakage current was visible in the export to anyone who opened it. The pipeline missed it. A user-level sanity check caught what the code did not.
Technical
Architecture
Python/Flask on localhost, SQLite persistence, pandas and NumPy for analysis, inline SVG for plots. Zero new dependencies were added to build this half on top of the existing anomaly detection tool — same ingestion pipeline, same database, same rule that only measured values are read.
Local only, single user, no cloud, no external calls.
Data sources
Telemetry comes from three independent devices on the electrical distribution serving the fan:
- A power meter — per-phase voltage, current, active power, power factor, cumulative active energy.
- A protection relay — earth leakage current.
- An upstream protection device — fault current as a percentage of its configured pickup threshold.
One-minute resolution. An earlier five-minute-resolution history existed and was deliberately excluded: mixing sampling rates would have required resampling decisions capable of introducing artefacts into a drift signal that is, by nature, small. A shorter record at one consistent resolution is more defensible than a longer record with a seam in it.
Data quality investigation
This was the largest part of the work. Three separate inconsistencies were found in the metering data, each of which would have corrupted the analysis if taken at face value.
Physically impossible readings at state transitions. During a recorded shutdown, current fell to zero on all three phases while the active power channel continued to report a non-zero value. Active power is derived from voltage and current, so this combination cannot occur physically — it indicates a channel synchronisation artefact, not an electrical state. Consequence: current is treated as the authoritative run-state indicator, and power as a secondary, lagging channel.
Non-comparable cumulative counters. Per-phase cumulative energy readings differed by orders of magnitude across three phases of a balanced motor. Rather than treat that as an electrical fault, I examined the counters across successive intervals and confirmed all three were incrementing normally. The disparity was independent counter start points, not imbalance. Consequence: cumulative energy is never used directly; all energy analysis runs on interval deltas, which cancel the arbitrary offsets.
Apparent precision that was not real. Readings are stored at full floating-point precision, so a current value arrives carrying nine significant figures. Those trailing digits are an artefact of binary representation and carry no sensor accuracy. Full precision is retained in storage and computation to avoid compounding rounding error across long series, but results are reported at two to three decimal places — the level at which a difference means anything for this instrumentation. A difference visible only at the eighth decimal place is noise, not degradation.
The general rule applied throughout: prefer direct measurements over derived or accumulated channels, and cross-check any suspected anomaly against an independent signal before treating it as real.
The comparison method
The question is not whether a single reading is abnormal but whether normal operating behaviour is moving over time. Defining normal was the substantive problem; detecting departures from it followed easily once the definition was sound.
The method compares like-for-like operating periods across weeks and quantifies per-channel change in:
- Steady-state current per phase, and averaged across phases
- Phase imbalance, as the spread between highest and lowest phase current
- Power factor
- Earth leakage current — the clearest indicator of insulation degradation
- Energy per unit time, from counter deltas
Comparison is restricted to periods where the fan is confirmed running, using current as the run-state indicator, so that start/stop transitions do not contaminate the drift measurement. Changes are reported both absolutely and as a percentage, since an absolute figure is uninterpretable without the operating level it is measured against.
Like-for-like means day type. Some days the fan runs all day, others only its scheduled window. Comparing a heavy week against a light week reads as degradation when it is usage. Splitting the comparison into event days and non-event days collapsed one phantom drift signal to zero.
Energised versus running. Earth leakage is an insulation property and flows whenever the circuit is live. Analysing it on running periods only produced nothing for a fan that barely ran. Leakage is now assessed against energised time, not running time.
Power factor is not compared across load levels. Motor power factor falls at light load, so a PF comparison between periods at different loads measures the load difference, not the motor. This comes from the machinery, not the statistics.
Methods
| Method | Used for |
|---|---|
| Otsu between-class variance on the current histogram | Learning each fan's idle/running threshold from its own data |
| Median + MAD (robust statistics) | Steady-state values that a single bad minute cannot skew |
| One-change-point L1 fit (minimise within-segment deviation) | Dating step changes correctly |
| P = V × I × PF cross-check | Catching physically impossible meter readings |
| Delta-based energy with reset and rollover guards | Cumulative counters that restart mid-log |
Counter resets and gaps are handled explicitly, because delta processing introduces two specific failure modes. A negative delta indicates a counter reset or rollover rather than negative consumption, and is treated as a segment boundary rather than a data point. A logging gap makes the following delta span a longer interval than expected, which would otherwise present as a consumption spike — so deltas are normalised by elapsed time rather than by sample count.
On the change-point fit. The first implementation dated a single repair event to three different dates on three channels. The reason: inside a stable run, the two segment medians barely move wherever you cut, so a formulation that maximises the gap between medians ends up choosing its split by noise. Refitting it as a proper change-point problem — minimising within-segment deviation — collapsed all three channels onto the same true date. The plausible-looking formulation and the correct one were indistinguishable in theory and differed sharply under real data.
Against a scored model
The original design produced one headline number: 67% risk of breakdown this week.
I removed it. I could not trust the figure, and more importantly I could not decompose it — when it read 55%, nothing in the output told me whether the insulation, a phase, or the load had moved. Each channel points at a different part of the system and a maintenance reader needs to see which one changed.
Splitting the output also reduces false positives, since a blended score can be pushed past a threshold by an accumulation of individually meaningless changes. The current output is a percentage per component, degrading or improving, compared across weeks.
Why no machine learning
The two core reasons carry over from Part 1: no training data existed, and the output directs a person who needs to be able to argue with it.
This half adds a third. Physical law is a better anchor than a learned threshold. A motor cannot generate power. Power factor cannot exceed one. P = V × I × PF must reconcile. These constraints need no training data and do not drift — and it was exactly one of them that caught the metering fault.
On AI-assisted development
Large parts of the code in this project were written with AI assistance. It would be dishonest to present it otherwise, and the distinction that matters is between building and running.
The analysis itself contains no AI. Same data in, same finding out, every time, defensible line by line. That was a correctness requirement, because the output directs an electrician to open a panel.
The generation of the code was a productivity choice. What it did not do was the thinking. AI tooling has no idea when its output is wrong — across this project it produced impossible values, flagged the wrong channels, and generated output that meant nothing. Every one of the decisions that made this tool work was one I made against its output:
- Recognising that the sawtooth output and the 0% health reading on a healthy board meant the synthetic-data approach was invalid.
- Rejecting the blended risk score for being undecomposable.
- Identifying that a heavy week compared against a light week was measuring usage, not degradation, and specifying the event/non-event split.
- Knowing that a hard-coded current threshold was the source of a four-figure phantom, and requiring the threshold to be learned per asset.
- Knowing that leakage is an insulation property and re-specifying the analysis around energised rather than running time.
- Testing the tool's "reversed CT polarity" diagnosis against the power factor magnitudes and correcting it to a phase-reference error.
Catching a wrong output is what gave me an area of the data to work on. The iterations that followed — this is version 1.3 — are where the value is, and further iterations will be needed as more data arrives.
Testing
463 automated assertions across the tool, all passing — 234 on the anomaly detection half, 229 on this one.
Fixtures deliberately reproduce the real faults found: an idle current sitting above the old hard-coded threshold, the two-phase wiring fault with a mid-log repair, and the idle fan with creeping leakage. Each production surprise became a regression test.
What's validated
Where validation actually stands
The usable record begins at the meter repair. Everything before it is corrupted by the wiring fault. Two weeks of trustworthy data have accumulated since, and collection is ongoing.
That is enough to show the method does not produce false positives on stable equipment. It is not enough to demonstrate that it detects degradation, because no monitored fan has degraded — there is no degradation present in the record to detect. Roughly six months of startup and running data is the target for real visibility of the fan's state.
Asked directly whether the fan is degrading, the honest answer is: not enough trustworthy history to say, and the tool says so itself. When it lacks sufficient clean data it reports that, along with the date from which data can be trusted. It never manufactures a verdict. A fabricated conclusion in a maintenance report is worse than no conclusion.
Validated
The engineering. 463 automated assertions, all passing, with fixtures modelled on the real faults found rather than invented failure modes.
The metering findings. Effectively confirmed by the repairs, which took place on consecutive days, and by the post-repair readings reconciling with P = V × I × PF.
Not validated
The predictive claim. No monitored fan has failed. Detection sensitivity, catch rate and false negative rate are all unknown, and none of them is estimable from the data available.
This is a matter of elapsed time rather than additional analysis. It is a build-and-watch phase, and the reports say so.
Why validation is genuinely hard here
No run-to-zero option. The equipment is in a live public facility. Running a fan to failure to observe the drift curve is not available, and should not be.
The preventive cycle competes with the measurement. Components are replaced on schedule, before a drift curve could accumulate enough history to be confirmed or refuted. The maintenance regime that keeps the facility running is the same one that removes the evidence.
It is hard to predict a fault that never happens. The core difficulty, stated plainly. Well maintained critical equipment supplies very few failure events, which is exactly why nobody has a labelled dataset for it, and exactly why the vendors sell sensors rather than proof.
Structural limitations
No corroborating signal on this asset. The instrumentation is electrical only. A mechanical fault — bearing wear, imbalance, misalignment — would need dedicated vibration or temperature sensing to be seen directly, and might reach the electrical channels late or not at all. On the fan there is no second signal to corroborate a finding against.
Drift direction is not a failure date. A comparison between two periods establishes that drift occurred and in which direction. Projecting to a failure date would require a trajectory across many periods and a validated relationship between drift rate and remaining life. Neither exists yet, and the tool does not imply otherwise.
Sampling resolution. One-minute sampling captures the approximate magnitude of a start-up current transient but not its detailed shape, which occurs over a much shorter interval.
Normal is learned from the asset's own history. A defect present since commissioning reads as baseline. This finds departures from habit, not absolute correctness — which is precisely why the sibling comparison and the physical-law cross-checks matter, since both provide a reference from outside the asset's own record.
The threshold is not yet set. What magnitude of drift should trigger action has not been fixed. Two sigma from baseline has been floated as a starting point, and it needs real operating history behind it before it means anything.
Anything that fails inside the normal range stays reactive. A fault that develops without moving any monitored channel outside its envelope remains a job for the ground crew. This tool does not change that, and it should not be presented as though it does.
On statistical rigour
The same caveat applies here as in Part 1: the thresholding and window-length decisions were made pragmatically, from what behaved sensibly against real data, rather than derived.
Worth adding one thing specific to this half. The technical methods used here are not sophisticated. Whatever value the work has lies in the data investigation that preceded them: establishing that a derived channel was unreliable, that cumulative counters were not comparable, that apparent precision exceeded real precision, and that a cyclical usage pattern was masking the signal of interest. None of that was anticipated at the outset. All of it was found by examining the data rather than assuming it was well-formed.
Future work
Accumulate the record
The immediate priority is time rather than code. Roughly six months of startup and running data is the target for real visibility of the fan's state — enough clean history to establish what this asset's normal genuinely looks like across seasons and duty patterns, rather than across two weeks.
Everything below depends on that record existing.
Set the threshold
What magnitude of drift should trigger action is not yet fixed. Two sigma from baseline is the working starting point, and it needs real operating history behind it before it means anything — a threshold set on two weeks of data is a guess with a Greek letter attached.
The threshold also has to be set against consequence, not just statistics. The cost of a false positive is a wasted inspection and a small withdrawal from the tool's credibility. The cost of a false negative is an unplanned outage in a public facility. Those are not symmetric and the threshold should not pretend they are.
The operating concept: maintain on condition, not on schedule
The reasoning the tool is built to support is deliberately conservative: no drift against baseline implies healthy.
That is a weaker claim than "predicting failure", and it supports a specific, useful action — pushing back preventive maintenance cycles on equipment that shows no evidence of change. The longer-term aim is maintaining on condition rather than on schedule.
Getting there needs the six-month record, an agreed threshold, and the maintenance team's confidence. Not one of those is a software problem.
Human in the loop, permanently
This is not a design phase to be exited. The tool produces a relative measure — this fan against its own past, or against its sibling. Published safety standards remain the absolute reference, and the maintenance team's domain knowledge stays in the decision path.
The tool's job is to direct attention. Deciding what to do about it is not its job, and building it so that it appears to make that decision would be the fastest way to lose the trust the whole approach depends on.
Second signals on the asset
The clearest structural gap is that the instrumentation here is electrical only. A mechanical fault may reach the electrical channels late, or not at all, and there is nothing on this fan to corroborate a finding against.
Closing that means dedicated sensing — which reopens the hardware question the project was deliberately built to avoid. My position is that the case for specific sensors on specific assets should be made after the existing telemetry has demonstrated its limits, not before. Arriving with a sensor budget request on day one is the vendor pitch that already gets declined.
Scaling
Each asset is a self-contained unit in the tool: upload its export, and every threshold and baseline is learned from that asset's own data. Onboarding a third fan is a file upload, not a configuration exercise.
The sibling-comparison pattern — the thing that turned a quiet leakage reading into an actionable finding — gets stronger with every asset added, because the reference set grows.
Extension to escalator drive motors
A parallel extension to escalator drive motors is in planning. It differs in an important way: no existing sensing is in place, so it required specifying vibration, current and temperature instrumentation from scratch.
That makes it a genuine test of whether the reasoning developed here transfers to an asset where the data has to be designed rather than discovered.
Status
Not a sanctioned pilot — no owner, no date, no budget. The programme-level position, and what would have to change, is set out in Part 1.