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