yau-plant-assistant/REQUESTS.md
Claude 5e0984b2cf Open the operator console to cicore1 only, without Authelia
An operator standing at the SCADA console should not complete a Duo push to
ask a question, and nobody outside the plant should reach the assistant at
all. The ai.yokogawa.tech Caddy block now admits remote_ip 10.0.0.21
(yau-poc-cicore1, static) and returns 403 to everything else. Applied on
lin001 2026-08-28; snapshot at ~/Caddyfile.bak-ai-scadaonly-20260828.

This also settles why the console could not reach the assistant at all:
auth.yokogawa.tech has no pinpoint record on the DC, so a LAN browser got a
correct 302 to the portal and then died on DNS. It went unnoticed because the
device agents write to Influx over the /api/v2/write MFA bypass and never
touch the portal - no browser had ever hit Authelia from inside the VNet.

Verified before applying that an IP matcher can work here: Caddy sees real
client addresses, and WireGuard peers arrive masqueraded as 172.19.0.6 so
they do not match and are refused along with the internet.

What this costs, recorded in section 14 as a shortcut and not as a security
control: it is an IP allowlist on a flat network with no OT/IT boundary, so
anything that can take 10.0.0.21 inherits unauthenticated access; Langfuse
traces are now anonymous, so there is no record of who asked what; and the
assistant is out of browser reach over the VPN. It is in scope for the
section 2 OT/safety review, which is still outstanding.

api.yokogawa.tech is unchanged and still fully gated - Phase 9 publishing
depends on Remote-User/Remote-Groups and stays there. The now-inert
ai.yokogawa.tech entry in the Authelia rule is deliberately left in place so
restoring the gate is a Caddy reload rather than an Authelia restart that
logs out every user on the host.

verify.sh treats 403-from-lin001 as the pass for the deny arm and states
plainly that the allow arm can only be proved from cicore1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 11:44:04 +10:00

9.5 KiB

Outstanding requests — WRPS Plant Assistant

Two things are still needed from other people, of the three originally raised. Nothing else is blocking: as at 21 August 2026 the assistant runs end to end on lin001 — the question box, name resolution, the data translator, document search, all four answer lanes, the rulebook, the working panel and the logbook are all live and were exercised by hand on the host.

Item 2 was delivered on 27 August 2026 and is closed — it is kept below as a record of what was asked for and what arrived. What is still missing is the AI model itself and real plant data. Both depend on someone outside this project and neither can be hurried at the end: the model account is the longest pole and also gates the OT/safety review, and the historian is the one furthest outside our control.

Contact for item 1: Daniel Watson (daniel.watson@yokogawa.com). Item 3 needs the owner of the imh historian, who is not yet identified.

# Request Needed for Blocks
1 Azure OpenAI account, 3 deployments The two AI steps — classifying the question, wording the answer Phases 6, 8; the safety review
2 Three public DNS records + DC pinpoint records Reaching the assistant by name from a control-room PC Delivered 27 Aug 2026 — closed
3 Read-only login to the imh historian Real plant figures instead of stand-ins Phases 4, 5; every data answer

1. Azure OpenAI account

Action

Create an Azure OpenAI resource in the existing subscription and deploy three models on it:

Deployment Model
Small chat GPT-5-mini class or equivalent
Flagship chat GPT-5 class or equivalent
Embeddings text-embedding-3-small

Hand over, via a secure channel: the endpoint URL, an API key, and the API version. Confirm outbound HTTPS from lin001 to the endpoint is permitted.

Pay-as-you-go. No fine-tuning and no provisioned throughput — both bill a fixed hourly amount whether used or not, and neither is needed.

Cost

Consumption-based, billed on usage only. No licence, no commitment, no minimum term, cancellable at any time. Estimated on three model calls per question at published list rates:

Usage Questions / month Estimated
Occasional demos 500 ≈ US$6
Expected — build, testing and demos 3,000 ≈ US$35
Heavy daily use 10,000 ≈ US$120

One-off cost to index the document set: under US$1.

Requested: a US$50 per month budget, approximately US$250 for the demo period, with an Azure budget alert set at that figure.

Rates are published list prices and should be confirmed at approval. This is a demonstration figure; an operational plant deployment would be sized and costed separately.

What it is for

The assistant runs end to end today except for the two steps that need a model: classifying each question, and wording the answer. Without the account those two cannot be built, tested or reviewed, and the 67-question acceptance test cannot be run at all.


2. Three public DNS records, plus pinpoint records on the DC — DELIVERED

Closed 27 August 2026. All three A records resolve to 20.211.144.151, and the DC carries the pinpoint record ai.yokogawa.tech → 10.0.0.17. Nothing further is needed from Dan for this item. Two things are worth recording:

  • api.yokogawa.tech and cube.yokogawa.tech have no pinpoint record, so they do not resolve from inside the VNet at all. That would have broken the operator demo, because the browser called the API by that hostname. Rather than ask for a fourth record, Caddy now routes /ask under ai.yokogawa.tech to ai-api and the page is same-origin. No further DNS is needed for the demo. cube.yokogawa.tech is for engineers on the public side only; ai-api reaches Cube container-to-container and never by hostname.

  • auth.yokogawa.tech has no pinpoint record either, and that was the defect this item missed. Confirmed 28 August 2026: it does not resolve from inside the VNet. Every Authelia-gated service redirects there, so a LAN browser reached ai.yokogawa.tech, got a correct 302 to the portal, and then died on DNS — the name resolved, the service answered, and the operator still saw "this site can't be reached". It went unnoticed because the device agents write to Influx over the /api/v2/write MFA bypass and never touch the portal; no browser had ever hit Authelia from inside the VNet. This is no longer needed for the operator path — on 28 August the console was made unauthenticated from cicore1 only (README §6, BUILD-AI-CONTAINERS.md §14) — but any other gated service browsed from the LAN will hit exactly this wall, so it is worth asking Dan for regardless.

  • The names resolving is not the same as the services answering. The Caddyfile blocks and the Authelia rules for ai, api and cube were applied on the host the same day; all four AI hostnames now return 302 to the auth portal. What is still unproven is the part no check here can reach: an operator on cicore1 — since 28 August, with no sign-in at all — getting an answer end to end.

The original request follows, unchanged.

What is needed

Three A records under yokogawa.tech, each → 20.211.144.151, the same treatment lf.yokogawa.tech already has:

Name Points at For
ai.yokogawa.tech 20.211.144.151 The operator's screen
api.yokogawa.tech 20.211.144.151 The assistant behind it
cube.yokogawa.tech 20.211.144.151 The data translator

And — separately, on the domain controller — a pinpoint record for ai.yokogawa.tech10.0.0.17. Azure hairpin means LAN hosts cannot reach the VM's public IP from inside the VNet, so without this an operator sitting at cicore1 cannot resolve the assistant at all. influx.yokogawa.tech already has exactly this treatment.

What it is for

All three services are running right now and none of them can be reached by name. Today they are opened down an engineer's SSH tunnel, which is fine for development and useless for a demonstration. No control-room PC can open the assistant until these records exist.

Caddy already holds the site blocks, each with import authelia, so sign-in and TLS are handled the moment the names resolve; certificates are issued automatically on first request. Access is governed by the existing HTTPS_UserAccess group — no new AD group is needed for this item.

Why raise it now

This is the item most likely to be forgotten, because nothing fails until the day somebody tries. Every container is healthy, every check passes, and the gap only appears when a person outside this project opens a browser. It also depends on two different people — public DNS and the DC are not the same change.


3. A read-only login to the imh historian

What is needed

  1. The server. yau-sls-poc-imh:1433 is configured and waiting; the host is still being built.
  2. svc_agent_ro created with SELECT on the agreed tables only — no DDL, no write access, no xp_ procedures. Password over a secure channel.
  3. The database name, and the agreed table names and key columns.
  4. NSG rule: lin001imh on 1433 only.
  5. Timestamp semantics confirmed: UTC or local, and DST behaviour. This one is not a formality — see below.
  6. Permission to set an application name on the connection, so DBAs can see who is connecting.

What it is for

Every figure the assistant produces today is a stand-in. Cube — the data translator — is running and answering questions against fixture tables (145 alarm records, 309 pump operations, about 130,000 level readings), and every answer built on one carries a warning label all the way to the operator's screen. The definitions Cube uses are the real ones and will not change when the historian arrives; only the source will.

Why the schema conversation cannot be deferred

Two defects found while hand-verifying Cube's measures were deliberately left unfixed, because fixing either against fixture data would mean guessing at what imh actually contains:

  • The wet well level tag does not join. History is keyed PS_STN_WET_WELL_LEVEL, but the tag seed carries that only as an alias of LIT-101. A tag-level lookup therefore returns zero rows for a third of the history — and reports it as "no records found", which an operator cannot distinguish from a genuine absence of data. Equipment-level lookup works, so whether a question fails depends on which path it takes. The likely fix is known, but must not be applied until imh says what CI Server actually historises the point as.
  • First/last alarm times return UTC, not site time. Inside a row labelled in Sydney time, the measure returns an instant labelled ten hours and a calendar day wrong. Which of the two available fixes is correct depends on what imh returns.

Both fail eval cases (H26, H27) until settled.

What it unblocks

Phase 4 and the remainder of Phase 5. Note that an engineer must independently confirm Cube's first real numbers by hand before anybody trusts one — that is a person's time, not just a login.


Phase 9 — operator document management will need a second AD group, AI_DocPublishers, with direct membership (Authelia resolves direct membership only; a user nested inside a group is silently denied). That is deliberately held until Phase 8 passes and is not being asked for now — noted here only so it is not a surprise later.