KB-3AEF

KB Protection Phase 1 Report

5 min read Revision 1
reportkb-protectiontriggers

KB Protection Phase 1 — Report

Date: 2026-04-04 | Session: S165 | Agent: Claude Code

Summary

Deployed PG trigger-based protection layer for Agent Data KB (kb_documents in incomex_metadata). Zero code changes. Triggers are transparent — API writes continue normally.

Investigation (Step 1)

Item Value
Target table kb_documents
Target DB incomex_metadata (user: incomex)
Schema key TEXT PK + data JSONB (all fields in JSONB)
Content path data->'content'->>'body'
Existing triggers 0 (NONE before this session)
Existing audit tables 0 in incomex_metadata
Sync mechanisms event_system.py -> directus_sync.py (async, knowledge/ prefix only)
Directus Flows 3 KB-related flows, ALL INACTIVE
Conflicts found NONE — clean install

Tables Created (incomex_metadata)

Table Status Purpose
kb_documents_history OK Full JSONB snapshot before each UPDATE/DELETE
kb_audit_log OK Lightweight write operation log (no content)

Triggers Created (on kb_documents)

Trigger Type Status Purpose
trg_kb_truncation_guard BEFORE UPDATE OK Warns when body shrinks >80% (>500 chars)
trg_kb_snapshot_update BEFORE UPDATE OK Saves OLD.data to history
trg_kb_snapshot_delete BEFORE DELETE OK Saves OLD.data to history
trg_kb_audit AFTER INSERT/UPDATE/DELETE OK Logs all write ops

Safety: All triggers use EXCEPTION WHEN OTHERS THEN RAISE WARNING — never block production writes.

PG Functions

Function Status Purpose
fn_kb_snapshot OK Snapshot trigger function
fn_kb_audit OK Audit trigger function
fn_kb_truncation_guard OK Truncation detection
fn_kb_restore(key, rev) OK Restore document from history

View

  • v_kb_recent_changes: Last 7 days write operations with severity

Safety Tests

Test Result
INSERT -> audit log PASS
UPDATE -> history snapshot + audit PASS
DELETE -> history snapshot + audit PASS
Truncation guard (body <500 skip) PASS (by design)
fn_kb_restore PASS (restored rev 1, content correct)
API POST /documents after triggers PASS (200 OK)
API DELETE after triggers PASS (soft-delete captured)
Qdrant + health probes OK (no disruption)

DOT Registration (directus DB)

Item Code Status
Domain kb (Quan ly tri thuc) Created
DOT_KB_PROTECT Tier B, event trigger Registered
DOT_KB_VERIFY Tier A, cron trigger Registered
DOT_KB_RESTORE Tier B, on-demand Registered
Paired PROTECT <-> VERIFY Set

Birth + Collection Registry

Entity Collection Status
kb_documents_history birth + COL-158 Registered
kb_audit_log birth + COL-159 Registered

Cron

0 21 * * * /opt/incomex/scripts/dot-kb-verify.sh >> /var/log/incomex/dot-kb-verify.log 2>&1

Scripts

  • /opt/incomex/scripts/dot-kb-verify.sh — daily integrity check (5 checks)
  • /opt/incomex/scripts/dot-kb-restore.sh — restore tool

First Verify Run

  • 303 docs with rev>1 but no history — expected (pre-trigger data, will populate going forward)
  • 0 truncation warnings
  • 0 suspicious short docs
  • PG active: 856

Directus Sync Note

Tables are in incomex_metadata (not directus), so Directus UI cannot see them. This is correct — they are infrastructure tables managed via SQL only.

Architecture

API Write -> PG kb_documents
  |-> BEFORE: trg_kb_truncation_guard (warn if shrink >80%)
  |-> BEFORE: trg_kb_snapshot (copy OLD.data -> history)
  |-> WRITE executes
  |-> AFTER: trg_kb_audit (log operation)
  |-> Event System (existing, unchanged)
  |-> Directus Sync (existing, unchanged)

Zero impact on existing write flow. Triggers are transparent.