Verify exact production traces and record rollout
This commit is contained in:
@@ -53,6 +53,44 @@ hand plus direct `/api/chat` probes — measured, not inferred from docs.
|
||||
evidence blocks unreachable from the prose, and provenance is a hard
|
||||
guardrail.
|
||||
|
||||
## Second batch — guardrail gaps (same day)
|
||||
|
||||
A guardrail review against `docs/architecture.md` found two things the design
|
||||
specifies that were not in the code. Both were implemented around the files
|
||||
currently carrying uncommitted changes, so nothing in that set was touched.
|
||||
|
||||
- **Rate limiting — new `apps/web/middleware.ts`.** `/api/chat` is public,
|
||||
takes no credentials and spends Bedrock credit per call against a small
|
||||
personal AWS budget; the architecture assigns this to `api-gateway`, which
|
||||
is not built. 12/min and 120/hour for `/api/chat`, 120/min for
|
||||
`/api/suggest` (a local catalog lookup, no model call), keyed on the
|
||||
left-most `X-Forwarded-For` entry that Caddy sets, returning 429 with
|
||||
`Retry-After`. Counters are per process and in memory: correct for the
|
||||
single `web` container in production today, and the point at which that
|
||||
scales past one replica is the point this has to move to Redis or to the
|
||||
gateway. It is a cost/abuse guard, not authentication.
|
||||
- **Disclaimer — `rag/answer.py` only, wire-up still pending.**
|
||||
`GroundedAnswer` now carries `disclaimer: str = DISCLAIMER` as a dataclass
|
||||
default, so no response path can be constructed without it, including
|
||||
abstains and clarifications. Deliberately a module constant and never sent
|
||||
through the generator: a model-written disclaimer can be reworded or
|
||||
dropped, and would then need verifying like any other generated claim.
|
||||
|
||||
### Wire-up left for whoever next owns `routers/rag.py`
|
||||
|
||||
`routers/rag.py` has uncommitted changes in this worktree, so the last step is
|
||||
left undone rather than edited around someone else's work. Two small changes
|
||||
complete it:
|
||||
|
||||
1. Add `disclaimer: str` to `RagQueryResponse` and pass
|
||||
`grounded.disclaimer` through when the response is built.
|
||||
2. `packages/shared-types/src/dto/chat.ts` already declares
|
||||
`disclaimer?: string`, so the BFF only needs to copy it onto the message it
|
||||
returns — no type change required.
|
||||
|
||||
Until step 1 lands, the guarantee exists in the domain object but is not yet
|
||||
visible to an API consumer.
|
||||
|
||||
## Files claimed
|
||||
|
||||
`apps/ai-service/rag/answer.py`, `apps/ai-service/rag/agent.py`,
|
||||
|
||||
Reference in New Issue
Block a user