yau-plant-assistant/api/tools
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
..
__init__.py Scaffold the WRPS plant operations assistant repository 2026-08-20 13:56:32 +10:00
equipment.py Refuse a retired PS_* name instead of finding nothing 2026-09-01 19:00:57 +10:00
metrics.py Key the whole seed on the CI Server item name 2026-09-01 19:00:38 +10:00
retrieval.py Identify the procedure first, then withhold its steps 2026-08-28 10:54:13 +10:00