# as-built — what is actually running

**Copied out of the live `openplc-runtime` container on 2026-09-02**, from
`/workdir/core/generated/`. This is the compiled artefact set the running PLC was
built from — the ground truth, as opposed to `../src/`, which is the intent.

> [!WARNING]
> **Do not edit anything in this folder and do not build from it.** It is a
> snapshot for reference and recovery. The editable source is `../src/`.

## Why keep it

The running PLC is a **`docker commit` image**. The compiled program lives in the
container's writable layer, not in a volume and not in any registry. If that image
is lost, and the OpenPLC Editor is still unavailable (`../DEPLOY.md` §0), this
folder is the only remaining copy of the compiled form of the program.

It is also the proof of what is deployed: you can read the C++ the PLC is actually
executing, rather than inferring it from the ST.

## Contents

| File | What |
|---|---|
| `program.st` | The ST as the Editor serialised and uploaded it |
| `generated.hpp` | STruC++ declarations for every POU and global |
| `pou_CONTROL.cpp` etc. | One C++ file per POU — the compiled logic |
| `configuration.cpp` | The task configuration: `plc_task`, 100 ms, three program instances |
| `generated_debug.cpp`, `debug-map.json` | Variable maps for the Editor's debugger |
| `program.st.map.json` | Line map from the generated C++ back to `program.st` |
| `strucpp_runtime/include/` | The STruC++ runtime headers the build needs |
| `conf/modbus_slave.json` | **The Modbus buffer layout** — `qw_count: 1024` is why `%MW0` is HR 1024 |
| `conf/ethercat.json` | 0 bytes. Emitted by the Editor by default; it is what leaves the EtherCAT plugin enabled for no reason. |
| `c_blocks.h`, `defines.h` | Small generated headers |

Built **2026-08-14**. Loaded as `libplc_1786668930820554523.so`.

## Verified against `../src/` on 2026-09-02

`program.st` was compared with `build/wrps.st` generated from `../src/`, after
stripping comments and normalising whitespace:

```
POU structure         identical - FB_PUMP, FB_DUTY_SELECT, FB_LEVEL_CTRL,
                      FB_HEADROOM, CONTROL, IO_MUX, SIMULATION,
                      CONFIGURATION Config0, three task instances
Non-declaration lines 0 differences, in either direction
Declaration lines     differ in formatting only - the Editor requires one
                      declaration per line, and holds VAR_GLOBAL in
                      project.json rather than in the ST
```

**The deployed program is this repo's source.** `../src/` is canonical, and the
running PLC agrees with it.

## Using this for an emergency change

If the Editor is unavailable and something must change *now*, the container can
rebuild from these files without any external toolchain — g++ 12.2 and Make are
inside it:

```bash
# on yau-sls-poc-lin001
docker exec -it openplc-runtime bash
#   edit core/generated/pou_*.cpp
./scripts/compile.sh          # rebuilds build/new_libplc.so
```

> [!CAUTION]
> **This is break-glass, not a workflow.** You would be editing generated C++,
> which immediately diverges from `../src/`, and the next proper deployment
> silently discards your change. The PLC also stops while it reloads. If you do
> it, record what you changed and port it back into `../src/` the same day.

Prefer restoring the Editor. See `../DEPLOY.md` §0.
