Commit graph

3 commits

Author SHA1 Message Date
Claude
bff4dec49a Document the env keys that were missing from .env.example
This file says "every key, no values" at the top and was not that, which cost
real time twice on lin001 in one day.

  - CUBEJS_DB_* was absent entirely, while ai-compose.yml states that Cube's
    database settings come from api.env. Deploying Cube meant reconstructing
    what it needed from compose comments and db/003_roles.sql. Added, with the
    pg-ai.env names its credentials come from, and a note that Phase 4 turns
    the block into an mssql connection against imh.

    Also recorded NEGATIVELY: not CUBEJS_EXT_DB_*. Cube v1 refuses Postgres as
    an external pre-aggregation store, so someone reading the older compose
    file will otherwise try to supply keys for a setting that must not exist.

  - NO_LLM_STUB, which is new and defaults to false here for the same reason it
    defaults to false in config.py.

  - The Langfuse keys were listed but not explained, and every way of getting
    them wrong is SILENT:

      absent          -> _langfuse() returns None, every question untraced
      mismatched pair -> a client is built, Langfuse rejects it, and main.py
                         swallows the exception by design

    Neither logs anything, in an answer path that is deliberately built never
    to break on observability. The symptom is identical - no traces - so
    correcting one cause while the other is still present looks like no
    progress at all. That is exactly what happened: a placeholder secret was
    pasted alongside a public key from a different pair, and the fix looked
    like it had not worked.

    So the file now says: they are PROJECT keys from the UI, not the server's
    own SALT/NEXTAUTH_SECRET in langfuse.env; they must be a matched pair; the
    secret is shown once and stored hashed, so it cannot be read back; and
    traces must be confirmed as ARRIVING rather than inferred from config.

No secrets here, including the masked tail of a real key - the example suffix
is invented.

The Langfuse fix itself is not in this commit and cannot be: it was two lines
in ~/ai/api.env, which .gitignore excludes on purpose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 15:49:35 +10:00
Claude
98083cd8d6 Design Phase 9 - operator document management
Operators cannot add a document today: ingestion is CLI-only, needs a host
login and a TTY for confirm_header(), /datadisk/ai-docs is mounted read-only,
ai-api has no identity, and nothing in the stack has a role that can write
doc_chunks. This designs the way in, the way out, and control over what is in
the retrieval pool. Design and schema only - no router, worker or UI code yet.

Documents in (16.1-16.9, db/004):
  upload -> pre-scan -> review -> approve -> published, with the header
  confirmation moved from a terminal prompt to a review screen and recorded
  rather than discarded. A CHECK constraint refuses an approved row without a
  confirmed number, revision and effective date, so an API bug cannot skip it.
  Three roles: agent_ro unchanged, uploads_rw writes the queue only, ingest_rw
  writes doc_chunks and has no HTTP surface.

Documents out (16.10-16.11, db/005):
  --supersede needs a revision to keep, so a cancelled procedure cannot be
  withdrawn at all. Adds withdraw (immediate, reversible, audited), restore
  (refused while another revision is live) and purge (off by default). A
  column grant plus a trigger let the web-facing role make a document less
  citable and never more.

The pool (16.13-16.15, db/006):
  pool_enabled, orthogonal to superseded: one is a claim about the document,
  the other about the corpus. Retrieval requires both, so re-enabling a
  withdrawn document does not make it citable. Named profiles and a
  per-request override let a demo trim the corpus without mutating state on a
  shared live host, and every reduced-pool answer carries a banner with the
  document count, following the used_fixture_data precedent.

Two existing defects found and documented while designing this:
  - ai-ingest takes PGUSER=agent_ro from api.env, a SELECT-only role, so the
    Phase 3 command in the README cannot write doc_chunks (16.1).
  - ingest_file() always inserts superseded = FALSE, so `--all` re-ingests a
    superseded revision as live. --supersede survives only until the next bulk
    run (16.10).

One commit rather than three: the upload, withdrawal and pool designs
interleave in the same spec, README and compose files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 13:17:38 +10:00
Claude
34d2ccc576 Scaffold the WRPS plant operations assistant repository
Build spec and host brief carried in from C:\Claude and WRPS/02-env; the
plant model (equipment, tags, alarm bitmask, enums, unit conversions) is
derived from WRPS/04-plc/register-map.csv, WRPS/05-scada/modbus/scada-points.csv
and WRPS-CTL-003.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 13:56:32 +10:00