# WRPS Plant Assistant — an index to this repository, and rules that are not advisory A proof-of-concept assistant that answers an operator's plain-English questions from plant data and controlled documents. It runs on `lin001`, an existing **live, shared** Docker host that is not ours alone. This file holds only what you must know *before* you act; everything else is a pointer. Keep it that way: put detail next to the thing it describes, not here. ## Where everything is | To understand | Read | |---|---| | What this is, and how to get oriented | `README.md` | | Why it is built this way, and the accepted shortcuts (§14) | `spec/BUILD-AI-CONTAINERS.md` | | The host, its history and its rules — **wins on any conflict** | `spec/YAU_Linux_Host_Onboarding.md` | | How to deploy or rebuild it | `spec/REBUILD.md` | | What is running right now | `status/current-state.html` | | What is blocked, and on whom | `status/REQUESTS.md` | | What is broken or unfinished, and ours to fix | `status/OPEN-ISSUES.md` | | To change | Go to | |---|---| | The safety contracts, one per answer class | `api/contracts.py` | | Which class a question gets | `api/classifier.py` | | The SQL allow-list and query caps | `api/guardrails.py` | | The document library screens — its docstring records how the build diverges from the design | `api/documents.py` | | How a document becomes searchable, and how it is found and cited | `ingest/ingest.py`, `api/tools/retrieval.py` | | How a question becomes a number | `cube/model/` | | Retention, windows and history measures | `api/tools/metrics.py` | | Plant facts, tags and equipment | `db/seed/tags.csv` | | The schema, roles and migrations | `db/*.sql` | | How a container is defined — networks, volumes, env files | `compose/ai-compose.yml` | | The operator's screen | `web/` | | SCADA namespaces and the delivered CI Server config | `db/seed/scada-source/README.md` | | The stand-in historian — some assumptions fail silently, not loudly | `db/README-standin-historian.md` | | Who can reach what | `caddy/ai-routes.caddy`, `authelia/access-rules.md` | | The eval set and its scorecard | `eval/` | ## The three lines this system does not cross 1. **No instructions for safety-critical actions.** Procedural answers give document identity, revision, effective date and verbatim prerequisites — never synthesised steps. 2. **No recommended setpoints or operating parameters.** Advisory answers give evidence and documented limits, then defer. Never a number presented as the answer. 3. **No answers outside the evidence.** Zero rows is "no records found", never a plausible figure. **These are code paths, not prompt instructions.** A safety rule living only in a prompt is not implemented. Fix failures in the classifier, Cube or ingestion — never by adding to the prompt. When a class is uncertain, choose the **more restrictive** one. ## Do not break these — a live host, and a live PLC - **`openplc-runtime` is live control.** Never restart, update or reconfigure it as a side effect of AI work, and never move its `10.0.0.17` binding to `0.0.0.0` — that binding is the only thing keeping unauthenticated Modbus off the internet. - **Never install on, write to or restart `cicore1`.** Never exceed read-only on `imh`. - **Never omit `import authelia`** from a Caddyfile block — it silently makes a service public. One deliberate exception exists for `ai.yokogawa.tech`; do not copy or widen it. - **Restarting Authelia or Caddy logs out every active user.** Announce it first. - **Growing data goes on `/datadisk`, never `/`.** Root is 62 GB and has hit 100% before. - **Publish no host ports.** Join the `proxy` network and go through Caddy. - **No secrets in Git, compose files, logs or error messages.** `0600` env files under `~/ai/`. - **`lin001` has 2 vCPU and 3 GiB. Do not build images on it if you can build elsewhere** and ship the image. When you cannot, check the host is quiet first — `uptime`, and who else is mid-demo — and say so before you start. `deploy.sh` builds on the host today, which is why this is a judgement and not an absolute. ## How to work here - **`docker ps` showing "Up" is not proof.** Run `scripts/verify.sh` and read the container logs. - **When an answer is wrong, prove Cube and retrieval by hand before touching the agent** — otherwise a wrong answer has four possible causes. - **Do not invent schema.** `imh` is still pending — inspect it, or ask. Fixtures are marked. - **Do not hand-edit generated files.** `db/seed/historian_items.csv` comes from `scripts/gen_historian_items.py`. - **Store UTC. Convert to local exactly once, in Cube.** Never do timezone maths in a prompt. - **A document is citable only after a human confirms its number, revision and effective date.** Never add a path that ingests an unconfirmed header. - **When something fails, pin it before you fix it.** A question answered wrongly goes in `eval/testset.jsonl`; anything provable without a model goes in `api/tests/`. Deployment and migration defects have no test home yet, so they go in `status/OPEN-ISSUES.md`. - **A defect you are not fixing now goes in `status/OPEN-ISSUES.md`** — read its header first; it says what belongs there and what belongs elsewhere. - **Never quote a count in prose.** Point at the file. Container counts, eval-set sizes and assumption counts have all gone stale in this repo; the file never does. - **Small commits, one concern each.** - **If a change alters an accepted phase, re-run that phase's gate.** - **Snapshot before you edit anything on the host** — config, database or seed. Name back-ups `.bak--`.