KB-6EA8

KB Phase 2 Restore + Security Lock

3 min read Revision 1
reportkb-protectionphase2securitys1702026-04-06

KB Protection Phase 2 — Restore + Security Lock

Date: 2026-04-06 | Status: ✅ RESTORED + LOCKED


1. Phase 2 Status (Restored)

Check Value
fn_kb_snapshot mode INSERT (no ON CONFLICT) ✅
fn_kb_snapshot RETURN NEW for UPDATE, OLD for DELETE ✅
UNIQUE constraint DROPPED (0 rows in pg_constraint) ✅
fn_kb_restore signature (text, timestamptz) → jsonb ✅
History count 1,948 rows, 206 unique docs, 158 multi-version ✅
updated_at column exists, NOT NULL, auto-update ✅

2. Security Lock

Object Owner Security incomex can?
fn_kb_snapshot workflow_admin SECURITY_DEFINER ❌ ALTER: "must be owner"
fn_kb_restore workflow_admin SECURITY_DEFINER ❌ ALTER: "must be owner"
fn_kb_audit workflow_admin INVOKER ❌ ALTER
fn_kb_truncation_guard workflow_admin INVOKER ❌ ALTER
fn_kb_updated_at workflow_admin INVOKER ❌ ALTER
kb_documents_history ❌ DELETE: "permission denied"
kb_audit_log ❌ DELETE: "permission denied"

Security Tests

SET ROLE incomex;
ALTER FUNCTION fn_kb_snapshot() → ERROR: must be owner of function ✅
DELETE FROM kb_documents_history → ERROR: permission denied ✅
CREATE OR REPLACE fn_kb_snapshot() → ERROR: must be owner ✅

Normal writes still work

SET ROLE incomex;
UPDATE kb_documents SET data = ... → UPDATE 1 ✅
History: 1946 → 1947 (trigger INSERT via SECURITY DEFINER) ✅

3. Retention Config

Table Key Value Description
kb_config history_retention_days 60 Days to keep. fn_kb_prune_history() reads from here.

fn_kb_prune_history(): SECURITY DEFINER, owned by workflow_admin. Deletes rows older than config days.

4. dot-kb-verify.sh Results (12 checks)

Check 1:  Post-Phase2 missing history: 4 (registries + empty key) — expected
Check 2:  Truncation warnings 24h: 2 (law move operations)
Check 3:  PG active docs: 893
Check 4:  Suspicious short docs: 0
Check 5:  Write activity 24h: 1146 UPDATE, 30 INSERT
Check 6:  Agent Data memory: 42.56% (1.064G/2.5G)
Check 7:  Permission guard: intact ✅
Check 8:  History: 1948 rows, 206 unique, 158 multi-version
Check 9:  updated_at: OK, 0 stale
Check 10: fn_kb_snapshot: INSERT mode ✅
Check 11: UNIQUE constraint: dropped ✅
Check 12: Size: History 3904 kB, Audit 696 kB
RESULT: 10/12 PASS, 2 WARN (expected — registries + law move truncation)

5. DOT Pairing (CP-12)

DOT Tier Paired With Cron
DOT_KB_PROTECT B (event trigger) DOT_KB_VERIFY
DOT_KB_VERIFY A (cron) DOT_KB_PROTECT daily 21:00 UTC
DOT-316 (trigger-guard) A KB_PROTECT + others daily 3:15 UTC

Phase 2 restored + security locked | workflow_admin owns all KB functions | incomex cannot modify