yau-plant-assistant/api
Claude f3c8020ac1 Refuse a retired PS_* name instead of finding nothing
With the seed rekeyed, a question asking after PS_STN_WET_WELL_LEVEL now
matches nothing - and the assistant answers "no records found". An
operator reads that as "the plant recorded nothing", not as "you asked
with a name this system retired". That is precisely the confusion the four
namespaces exist to prevent, and an empty result is the wrong shape of
answer for it.

equipment.resolve() now rejects those names up front, raising
ContractViolation, which main.py already turns into an error rather than
an answer. The message says what the name was, why it is not a tag, and
what to use instead.

The four Modbus poll groups keep the prefix legitimately - they are
groups, not names, and nothing resolves an operator term onto one - so
PS_STATUS_BITS, PS_PUBLISHED, PS_SETPOINTS and PS_SIM_CONTROL pass.

Scope, deliberately small: this covers equipment.resolve(), the path an
operator's words take. Calling metrics directly with a retired id is not
covered. For a demo that is the right trade; for production it is not.

Verified by lifting the guard's own source out of the file and exercising
it - upper case, lower case, surrounding whitespace, the _SP variant, all
four poll groups, and the item, instrument and plain-English forms. The
module itself could not be imported here: no psycopg on this machine.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 19:00:57 +10:00
..
tests Fix three defects the first real document exposed 2026-08-28 15:03:31 +10:00
tools Refuse a retired PS_* name instead of finding nothing 2026-09-01 19:00:57 +10:00
agent.py Remove the shift log: not properly designed yet 2026-09-01 14:29:38 +10:00
app_healthcheck.py Scaffold the WRPS plant operations assistant repository 2026-08-20 13:56:32 +10:00
chunking.py Fix three defects the first real document exposed 2026-08-28 15:03:31 +10:00
classifier.py Take the facts back off the model 2026-08-28 10:54:29 +10:00
config.py Add the document library screens: upload, review, withdraw, restore 2026-08-28 14:13:17 +10:00
contracts.py Take the facts back off the model 2026-08-28 10:54:29 +10:00
convert.py Fix three defects the first real document exposed 2026-08-28 15:03:31 +10:00
Dockerfile Add the document library screens: upload, review, withdraw, restore 2026-08-28 14:13:17 +10:00
documents.py Fix three defects the first real document exposed 2026-08-28 15:03:31 +10:00
guardrails.py Pin the site timezone on every Cube query 2026-08-21 15:23:27 +10:00
identity.py Add the document library screens: upload, review, withdraw, restore 2026-08-28 14:13:17 +10:00
main.py Add the document library screens: upload, review, withdraw, restore 2026-08-28 14:13:17 +10:00
requirements-docs.txt Add the document library screens: upload, review, withdraw, restore 2026-08-28 14:13:17 +10:00
requirements.txt Scaffold the WRPS plant operations assistant repository 2026-08-20 13:56:32 +10:00
stub.py Add NO_LLM_STUB: the whole chain, working, without a model 2026-08-21 15:24:25 +10:00