Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/branch-review-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -660,3 +660,4 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD
| 2026-07-20 | claude/clinical-kb-pwa-review-asi3wb (PR: RAG memory + safeguards) | see PR head | User-directed close-out: durable RAG behaviour memory (docs/rag-behaviour/, 4 files) + AGENTS.md standing protection rules + ENFORCED safeguards — pr-policy blocking `RAG impact:` gate on protected surfaces (self-tested: undeclared/vague blocked, no-change/canary declarations pass) + source-pin contract test on imputation formulas and release comparator key order (red-proven vs a mutated constant). Confirmation canary #56 (29774459706, reverted main 0a498e6): SUCCESS — 36/36 restored, closing the #55-regression→revert→restore arc live. Phase D complete (D-1 ref input #1003, D-2 eval:trend #1006, D-3 policy §3.1 #1006, D-4 latency in trend rows); remaining documented plans: word-boundary matcher (own PR), irrelevant@10 labeling audit, Phase E (separate approval). Spend ≈$5-10 of ≤$20. | pr-policy self-test + workflow guard PASS; contract test 4/4 + red-proof; npm run test 3025 passed / 1 known container pdf-budget artifact; lint+typecheck+prettier clean; docs:check-links 1030 refs PASS; check:github-actions PASS |
| 2026-07-20 | claude/clinical-kb-pwa-review-asi3wb (PR: matcher + artifact follow-ups) | ab145f6 | Remaining documented improvements implemented: word-boundary textContainsClinicalTerm + top-10 canary artifact rows | Matcher: boundaries + internal separators widened to any non-alphanumeric run — PROVEN strict superset by artifact replay on canary #53 (1,126 term×alias×result comparisons, 0 lost matches, 7 gained = exactly the previously-documented punctuation-joined occurrences: treatment,/mood,/(opioid/ptsd.[35]/ciwa-ar ×3). More-tolerant measurement cannot fail a passing case → weekly scheduled canary = free live confirmation. Exported + 3 direct unit-test groups (superset preservation, audit classes incl. line-broken 'ciwa- ar' and 'full-blood-count', substring-inside-word rejections). Artifact: topResultSummary 5→10 rows so rr@10/irrelevant@10 metrics' actual inputs are captured — unblocks the offline irrelevant@10 labeling audit next artifact. docs/rag-behaviour updated to implemented state. Phase E remains gated on separate approval. | Targeted vitest 59/59; npm run test 3028 passed / 1 known container pdf-budget artifact; lint+typecheck+prettier clean; audit script run recorded above; no provider calls |
| 2026-07-20 | claude/clinical-kb-pwa-review-asi3wb (PR: DB easy wins) | see PR head | User-requested database + process easy-wins pass: read-only Supabase advisor sweep (user-authorized) → canary-liveness probe + advisor-disposition docs; live mutations withheld for per-item confirmation | Advisors (live, read-only): security = 1 INFO (document_title_words RLS-no-policy = the deliberate fail-closed pattern — now comment-documented at the schema block so it is never 'fixed'); performance = ~33 unused-index INFOs + auth connection-strategy note → docs/db-maintenance.md TRIAGE list with retrieval-surface trgm indexes flagged RAG-protected (dropping = full canary protocol), owner-scoped indexes retained for multi-tenant design, operational candidates deferred (negligible benefit at corpus size). Implemented: ci.yml static-pr warn-only eval-canary staleness probe (actions:read, github-script pinned, >8 days → warning; never fails) — needed because #923 (2026-07-19) moved the canary cadence from daily to weekly Sunday 18:00 UTC, where a dropped fire would go unnoticed for a week (the failure-issue step only reacts to runs that happen). CORRECTION (CodeRabbit review on this PR): the initially recorded "2026-07-20 dropped Sunday fire" incident did not occur — 2026-07-20 is a Monday; the Sunday 2026-07-19 slot fired as scheduled run #48 (19:03 UTC, success), and under the weekly cron no 2026-07-20 slot existed. Probe stands as proactive hardening, staleness now measured from updated_at with a finite-timestamp guard. Presented for confirmation (NOT implemented): scheduled telemetry retention (purge:query-logs is owner-scoped + unscheduled; needs owner/window/policy decision), auth percentage connection strategy (dashboard config), any index drops. | check:github-actions PASS; check:ci-scope PASS; check:function-grants 28/28 PASS; docs:check-links 1034 PASS; supabase-schema vitest 66/66; lint+typecheck+prettier clean; Supabase access read-only only |
| 2026-07-20 | claude/clinical-kb-pwa-review-asi3wb (restarted from e6cd6cb; PR: telemetry-retention correction) | 01368ff (+0144e69 main merge-in) | User-directed "implement your recommendation for all decisions" close-out: the scheduled-retention recommendation is RETRACTED as founded on a false premise — telemetry retention is ALREADY ACTIVE inside the database via pg_cron; docs corrected, nothing built, no live mutations | Fresh read-only cron.job verification (2026-07-20) matches docs/privacy-impact-assessment.md §6 exactly: jobid 11 purge-expired-rag-queries daily 03:30 (30d), jobid 12 purge-rag-retrieval-logs daily 03:00 (90d), jobid 13 purge-rag-query-misses daily 03:45 (90d), jobid 16 purge-rag-response-cache hourly (bounded 1000); v3 worker jobs present-inactive under backlog auto-toggle (jobid 10); obsolete unbounded cache job absent; audit_logs indefinite by design. db-maintenance.md "open decision" section replaced with the resolved state; purge:query-logs clarified as the MANUAL owner-scoped tool (not the retention mechanism). A GitHub-side weekly deleter would have duplicated pg_cron with window drift (a 90d rag_queries sweep can never out-delete the live 30d job). Remaining decisions stand as documented no-action: auth percentage connection strategy deferred to next instance resize; operational index drops not recommended. | prettier + docs:check-links PASS; Supabase access read-only (single cron.job SELECT, user-authorized read-only envelope); no workflow/schema/config changes |
35 changes: 26 additions & 9 deletions docs/db-maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,32 @@ replay + (for retrieval tables) canary pair — never a bulk advisor-driven swee
(magic-link/OAuth only). Revisit at the next instance-size change (dashboard config —
confirmation-required).

## Telemetry retention — open decision (2026-07-20)

`rag_queries` / `rag_retrieval_logs` telemetry grows with live and eval traffic.
`npm run purge:query-logs` exists (owner-scoped, `--older-than-days`, `--dry-run`,
fails loudly on unknown flags) but is **scheduled nowhere** — retention is currently manual
and unbounded. Wiring a schedule is deliberately NOT done unilaterally because it is a
recurring live-deletion job needing an explicit policy: which owner scope, what retention
window (script default 90 days), and where it runs (a small weekly workflow with the
service-role secret is the natural home). Decision recorded here when made.
## Telemetry retention — RESOLVED: already active in pg_cron (verified live 2026-07-20)

An earlier revision of this section called retention "manual and unbounded" after finding
`npm run purge:query-logs` scheduled nowhere. That premise was wrong: retention runs INSIDE
the database via pg_cron, not in CI. Read-only `cron.job` verification (2026-07-20) matches
`docs/privacy-impact-assessment.md` §6 exactly:

| jobid | Job | Schedule (UTC) | Window / mechanism |
| ----- | --------------------------- | -------------- | -------------------------------------------------- |
| 11 | `purge-expired-rag-queries` | daily 03:30 | `purge_expired_rag_queries(30)` — 30 days |
| 12 | `purge-rag-retrieval-logs` | daily 03:00 | raw delete where `created_at` older than 90 days |
| 13 | `purge-rag-query-misses` | daily 03:45 | `purge_expired_rag_query_misses(90)` — 90 days |
| 16 | `purge-rag-response-cache` | hourly at :15 | `purge_expired_rag_response_cache(1000)` (bounded) |

All four are active; the obsolete unbounded cache job remains absent; `audit_logs` retention
is indefinite BY DESIGN (compliance note in migration `20260702120000` — do not add a purge
without compliance review). **No GitHub-side retention workflow is needed, and none was
added**: a second scheduled deleter would duplicate pg_cron and invite window drift — the
once-proposed weekly 90-day sweep of `rag_queries` could never delete anything the 30-day
job had not already removed. Retention windows are PIA-governed privacy decisions; change
them via migration + PIA update, never ad hoc.

`npm run purge:query-logs` is the MANUAL owner-scoped deletion tool (privacy requests,
targeted eval-owner cleanup; requires `--owner-email`, supports `--dry-run`, default 90
days). It is deliberately unscheduled — it is not the retention mechanism, and its absence
from cron is not a gap.

## Cross-references

Expand Down