Tool-life forecast · trained and verified

What a model would do here — and what it would not be allowed to

ZenFactory works rule-based. Machine learning here is not a rebuild but a plug: the docking point is built and tested, and since 24 August 2026 the first model has been sitting in it — zf-standzeit, trained on 89 blade lives from our own historian. It proposes nothing; it merely knows earlier. This page shows what of it is measured and what remains illustration — plus four instances that can say no to a model too, without a line of it being changed.

The view

Shown on the band saw in cutting, because that is where the most interesting case lies: this machine has no manipulated variable. A model cannot adjust anything here — it can only know earlier what will happen anyway.

Site 1 · Cutting · Saw blade

Tool-life forecast

Illustration · sample trace

Cuts since blade change

300

of 380 nominal — tool life per nameplate

Motor current

15,3 A

fresh blade 11.5 A · threshold 15.8 A

Change expected in

42 ± 12

cuts, about 32 min of plant time

Model quality

± 7,9

cuts — the resolution of the line. 0.9 was measured; see below for why the larger number is the honest one.

Motor current over the blade’s tool life

SAEGE01 · OperationalData.MotorCurrent
Threshold 15.8 Anow · 3003420 cuts400
measured, from the historian forecast uncertainty band

The model reads nothing that is not already in the twin: motor current, cut time, remaining-life display, miscut rate. The benefit is not the curve but the lead time — a blade change takes a quarter of an hour, and planned it costs less than when it surprises you.

Observation without a rule

no proposal

R01 · heat-up phase 9 % longer than in the last 40 comparable batches, at an unchanged setpoint.

Expected
18.4 min
Measured
20.1 min
Outside since
6 batches

No rule set covers this. That is why it appears as an observation for maintenance — and not as a proposal in the control loop.

Model card

trained
Name
zf-standzeit
Version
0.1.0
Feature
Motor current, nothing else
Learned on
89 blades · 4,854 examples
Verified on
30 held-out blades
Mean error
0.9 cuts
Resolution of the line
7.9 cuts

No longer a placeholder: the values are in ml/zf-standzeit.json and come from the run of 24 August 2026. Version and quality measure go into the same chain as any intervention as provenance — otherwise it could not later be said which state supported a decision.

Proposal from the model

awaiting approval

ST020 · feed

0,96 → 1,02

Forecast
+9.4 parts/h
Noise band
± 6.1 parts/h
Gate
assumed

Generated by the model, but in the same format as a proposal from the rule set: limited step, forecast as a number, trial run afterwards.

Rejected by the gate

2 reasons

CNC03 · feed

1,00 → 1,11

Step size
0,11 > 0,08
Last change
9 min ago
Gate
rejected

The gate does not check where a proposal comes from. A model gets the same limits as a rule — and the same rationale when it exceeds them.

Where the model docks on

The model replaces nothing. It sits alongside the rule set and produces the same kind of finding — everything after that stays as it is. The socket for it is built; what was missing is the plug.

That is the real statement: the value of the existing architecture is that it does not have to take a learning component on trust. Forecast, gate, approval, trial run, watchdog and ledger are already there — and they do not ask where a proposal comes from. As of this version that is no longer only stated here but sits in loop/adapter.py.

  1. M

    Monitor

    unchanged

    Reads the AAS twin, time-weighted. The same source from which the model would also draw its features.

  2. +

    Adapter

    built, empty

    The docking point exists: an adapter is anything that masters beurteile(Beobachtung, Schwellen) and returns a finding or None. A model would be a service that serves exactly that — it writes nowhere and calls nothing. It is plugged in at loop/analyze.py, where the rule set is already chosen today.

  3. A

    Assess and plan

    unchanged

    The finding becomes a limited proposal with a predicted effect. Whether the finding came from a rule or a model changes nothing about that.

  4. 1

    The gate

    unchanged

    Limits, step size, minimum confidence, observation period, spacing, repeat lockout. A YAML file that also applies to model proposals.

  5. 2

    The human

    unchanged

    Approval required. A model does not shift this threshold — it would first have to earn it over weeks of confirmed forecasts, just as the rules did.

  6. 3

    Trial run and watchdog

    unchanged

    The measured effect decides, not the predicted one. Whatever delivers less than announced goes back — even if a model proposed it.

  7. K

    Ledger

    one more field

    Every proposal carries its provenance in the evidence: rule or the adapter’s name@version. It is written by the loop, not by the adapter — whoever may write down their own provenance will at some point write down the wrong one. That is the only change to the chain of evidence, and it is the reason why it can later be said which version was responsible for what.

The contract

in the repository

Three sentences, and they stand as code, not as intent: an adapter answers an observation with a finding — or with None, and then the rule answers. If it fails, that costs one cycle and not the plant. And it gets no special rights: its finding goes through the same gate, the same approval and the same trial run.

# loop/adapter.py — what an adapter must be able to do
class Befundgeber(Protocol):
    name: str
    fassung: str
    def beurteile(b, schwellen) -> Befund | None: ...

# loop/analyze.py — the order is the whole promise
befund = adapter.beurteile(b, schwellen)   # if it returns None or fails:
befund = regelwerk.beurteile(b, schwellen) # the rule answers

# plug in without changing a line
ZENFACTORY_ADAPTER=LINIE_A=pruefstecker

# and prove that the socket holds
.venv/bin/python -m pytest tests/test_loop.py -k adapter   9 passed

The Prüfstecker (test plug) is not a model and does not pass itself off as one. It is the counterpart of the test plug in a network socket: it hands the plant rule’s verdict back under its own name and with dampened confidence. That lets you show at the meeting that a finding comes through the adapter, appears in the ledger with its provenance and is treated by the gate like any other — without a physics having to be invented anywhere for it.

What the model really says today

The model has existed since 24 August 2026. It is not a neural network, it needs no GPU and not a single additional library — it is a straight line through a point cloud, calculated in pure Python.

# .venv/bin/python ml/train_standzeit.py --tage 2
Model       remaining cuts = 1286.9 - 78.6 · current[A]
Learned on  89 blades, 4,854 examples
Verified on 30 held-out blades, 1,647 examples
Error       0.9 cuts on average (mean alone: 96.2)
Resolution  7.9 cuts per 0.1 A step — the limit of the line

# .venv/bin/python ml/train_standzeit.py --jetzt
20:59:26  Motor current 13.3 A
Remaining life  241 cuts
Model           zf-standzeit@0.1.0

One feature

Motor current only

Wear and remaining life are available in the simulation — the model never gets to see either. On a 1998 saw they do not exist, and a model that only looks good at the meeting because it already knows the answer is worthless.

The labels

Arrive on their own

Every blade change labels its own history retroactively: at cut 300 there were still 80 to go, and that is known afterwards. 119 completed blade lives in 34 hours — the most expensive part of an AI project falls away here.

The limit

7.9 cuts per step

The current arrives in steps of 0.1 A over Modbus. One step is 7.9 cuts — this forecast can never get better than that on this line, whatever method is behind it.

A classification nobody else supplies: The 0.9 cuts apply to a clean signal. On the replica plant the current follows the wear exactly — without scatter from material, feed or temperature. How much of that is left on a machine with real noise, we have measured rather than left open:

What remains when the signal scatters

The saw can put scatter on the motor current — two thirds as a material batch that carries over sixty cuts, one third as measurement noise. Out of the box this is switched off, so that the other numbers on these pages match the pure formula. When it is switched on, the same model is retrained at each level and verified on held-out blades:

Scatter on the currentMean error80 % bandMean alone
off2,0−3 to +394,9
1 %6,6−11 to +1094,8
2 %12,8−22 to +1894,8
5 %29,7−51 to +4394,8
10 %50,6−86 to +7794,8

All in cuts, 28 blade lives per level, current rounded to 0.1 A. Recompute with scripts/sweep_streuung.py.

Five percent scatter is not a large number on a band saw — a different material batch shifts the current slightly, by a third of an ampere. There the forecast lies at ±30 cuts instead of ±1. That is still three times better than the mean, but it is no longer an appointment you plan to the day — it is a shift. This number belongs in a quotation, not the 0.9.

Where the data would come from

For a tool-life forecast the historian is enough: wear curves arise by themselves, every blade change is an example with a known outcome. For a model that proposes manipulated variables it looks different. Its labels would be the verdicts from the evidence ledger — and so far there are too few.

What is thereVolumeGood for
Wear curves
Motor current, cut time, miscuts per blade
ongoingTool-life forecast. Arises without any effort, outcome always known.
Historised KPIs
every change a row, since the start
ongoingAnomaly detection. Needs no labels, only enough normal operation.
Assessed attempts
Proposal, forecast, measured effect, verdict
59Too little for a manipulated-variable model. 15 confirmed, 44 rolled back — as a training set these are individual cases.

Prerequisite 1

Effect must be separable from noise

Today output fluctuates at an unchanged manipulated variable by ±14 % on the line, ±25 % at the filling line, ±77 % at the reactors. A model learns the noise from that first. The paired comparison against an unchanged sister unit is therefore not a side project but the precondition.

Prerequisite 2

Enough attempts, and from operation

59 assessed attempts are a good track record and a poor training set. They grow only in live operation — and each one costs a trial run of two to six hours of plant time.

Prerequisite 3

Fallback to the rule

If the model service fails or delivers nonsense, the loop must keep running — with the rule set that exists anyway. A model may be a supplement, not a dependency. That is the only one of the four prerequisites already fulfilled: failure, silence and nonsense from an adapter are one test each, and all three end at the rule set.

Sequence

First where nobody adjusts anything

Tool life and anomaly are pure observation: being wrong costs attention, not scrap. The start belongs there — and not at the manipulated variable of a running plant.

The status in three sentences. The docking point is built and secured: contract, fallback to the rule, provenance in the ledger, plus tests for failure, silence and wrong answers. The model is trained and captures the saw’s physics; it delivers findings for maintenance and adjusts nothing because this machine has no manipulated variable. It learned on the replica plant — when used on your machine it is retrained on your data, and the measurement for that runs exactly as it does here.