KB-1FCF

RE-AUDIT REPORT — Claude — 2026-03-15

11 min read Revision 1

RE-AUDIT REPORT — Claude — 2026-03-15

Phạm vi: Re-audit toàn diện sau S124 fixes (PRs #511-#514) Tài liệu: 14 architecture docs + 4 S124 reports + 3 audit lần 1 Phương pháp: Đọc tài liệu → SSH production PG → Curl APIs → so sánh 3 nguồn

TÓM TẮT

  • 🔴 Critical: 2 vấn đề
  • 🟡 Warning: 6 vấn đề
  • 🟢 OK: 12 lĩnh vực
  • ✅ S124 fixes verified: 11/13 (2 có bug)

I. NHẤT QUÁN TÀI LIỆU

🟢 Hiến pháp 25 Điều — Nhất quán

Không phát hiện mâu thuẫn nội bộ mới. Chuỗi logic Điều 0→0-B→21→24 liền mạch.

🟢 Operating Rules v4.24 vs Hiến pháp

S124 đã fix lệch Assembly Gate (6Q thay 5Q). Collection Creation Checklist 8 bước đã thêm. Nguyên tắc Fix Gốc đã codify.

🟢 Số liệu khớp production

  • v_registry_counts: 20 entries, 0 MISMATCH (verified)
  • verify_counts(): 0 rows WHERE status != OK
  • Sync gap: AD=199, DX=199, Gap=0
  • DOT: 112, taxonomy: 55, entity_labels: 1912, system_issues: 707 open + 31 archived

🟢 Tech Debt status consistent

15 TDs marked resolved in S124 — verified resolved on production.


II. LỖ HỔNG KIẾN TRÚC

🔴 v_all_entity_codes VIEW thiếu 3 tables

Production check: CAT-014 (table_proposals), CAT-015 (checkpoint_instances), CAT-016 (registry_changelog) NOT in v_all_entity_codes VIEW.

Evidence: SELECT in_view FROM meta_catalog... → table_proposals=f, checkpoint_instances=f, registry_changelog=f

Impact: entity_code orphan detection via VIEW incomplete. dot-label-validate (future) will miss entities from these 3 tables.

SELECT COUNT(*) FROM audit_dead_links() → 119 rows. These are entity_dependencies records pointing to non-existent entities. Sample:

  • workflow_steps.checkpoint_set_id → checkpoint_sets (FK reference issues)
  • workflows.parent_workflow_id → workflows (self-ref orphan)

These are real data integrity issues from S120 audit. Still open as system_issues (type=link_hỏng). Not blocking but accumulating.

🟡 4 tables missing auto-code (trg_auto_code_*) trigger

  • comments (no code generation — acceptable, comment IDs)
  • registry_changelog (log collection, uses entity_code not PREFIX)
  • system_issues (ISS codes now generated by PG trigger BUT trigger only fires on INSERT via Directus flow, not direct PG insert)
  • taxonomy (uses LBL codes but no auto-generate trigger — manual codes OK for taxonomy)

🟢 PG constraints solid

Taxonomy: 5 CHECK constraints + composite FK + cycle detection + parent_facet auto-fill. All verified.

🟢 Trigger matrix comprehensive

58 custom triggers across 19 tables: auto-code (15), count (20), label-assign (19), taxonomy-specific (4). Well-organized.


III. LỖI MÃ NGUỒN

🔴 deprecate_entity() has logic bug

Bug location: EXECUTE format('...RETURNING $3', ...) USING 'deprecated', p_entity_code, v_collection INTO v_collection;

Issue: RETURNING $3 returns the 3rd parameter ('deprecated' literal) instead of the collection name. Then v_collection gets overwritten with 'deprecated'. The detail message becomes "Updated deprecated status to deprecated" instead of the correct collection name.

Root cause: The EXECUTE uses $3 in RETURNING which refers to the USING parameter v_collection (which is the original collection name), BUT the result is stored back INTO v_collection, overwriting it with whatever RETURNING gives. Since RETURNING $3 means "return the 3rd bind param" = the old v_collection value, it actually works by accident — but only because $3 happens to contain the collection name at that point. The code is fragile and confusing.

Recommendation: Replace with a separate UPDATE + GET DIAGNOSTICS or use a dedicated variable for the result.

🟡 fn_auto_label_assignment UPDATE guard includes 'title' but most triggers don't fire on title change

The function checks (to_jsonb(NEW)->>'title') IS NOT DISTINCT FROM (to_jsonb(OLD)->>'title') in the UPDATE guard. But only 2 triggers fire on title change (workflows, table_registry via UPDATE OF title). Other triggers fire on UPDATE OF name, description — so the title guard is dead code for those tables. Not a bug, but unnecessary complexity.

🟡 refresh_registry_count_issues counts WHERE status='open' but refresh_registry_count (generic) counts ALL rows

System_issues has a custom count function counting only status='open'. But the generic refresh_registry_count counts ALL rows. If a table has both custom and generic triggers, the generic one could overwrite the custom count. Currently no conflict because system_issues uses ONLY the custom trigger, but if someone adds system_issues to the generic trigger loop, counts will be wrong.

🟢 PG functions: NULL handling adequate

All functions use COALESCE for NULL fields. fn_auto_label_assignment returns NEW early if entity_code is NULL. chk_no_cycle returns NEW if parent_id is NULL. No NULL-related crashes found.

🟢 Taxonomy constraints: cycle detection tested and verified

chk_no_cycle walks up to 5 levels. chk_replaced_by_valid walks up to 5 levels. Both properly RAISE EXCEPTION.


IV. NỢ KỸ THUẬT

TDs resolved — verify status:

All 15 S124-resolved TDs verified on production. Key verifications:

  • TD-165: sync gap=0 ✅
  • TD-174: code_column from v_registry_counts ✅ (verified in fn source)
  • TD-175b: orphan CAT-016=0 ✅
  • TD-176: ISS codes for 31 pre-S116 ✅
  • TD-179: Health Check CHECK 9 GREEN ✅

TD mới phát hiện:

TD Mô tả Mức
TD-NEW-1 v_all_entity_codes missing 3 tables (table_proposals, checkpoint_instances, registry_changelog) 🟡
TD-NEW-2 deprecate_entity() RETURNING bug — confusing variable reuse 🟡
TD-NEW-3 119 dead links still unresolved (system_issues type=link_hỏng) 🟡

V. AUTOMATION GAPS

🟢 Health Check 9/9 GREEN

All 9 checks verified passing. CHECK 9 (Registry Integrity) correctly validates 20 collections, DOT≥100, taxonomy≥50.

audit_dead_links() returns 119 issues. audit_relationships() shows missing relationship data. Neither is in the Health Check workflow. If dead links grow to 500+, no automated alert fires.

🟢 DOT coverage: 112 tools, 19/19 collections fully wired

dot-coverage-inspector shows 0 blind spots. All collections have: count trigger, changelog flows (or exemption), label trigger.

🟡 Self-healing still detect-only

Pipeline: DETECT → ALERT (system_issue). Missing: CLASSIFY → PROPOSE → APPLY → VERIFY. 707 open issues, 0 auto-resolved. The deprecate/retire functions are available but require manual invocation.


VI. BẢO MẬT & HIỆU NĂNG

🟡 system_issues publicly accessible via Directus API

curl https://directus.../items/system_issues → returns data without auth. This leaks internal system diagnostics (error descriptions, entity codes, severity levels) to any internet user.

🟢 Sensitive collections properly blocked

taxonomy, entity_labels, label_rules, directus_users → all return 403 for public access.

🟢 v_registry_counts public access acceptable

Registry counts are non-sensitive metadata. Public access enables the Nuxt SSR to render Layer 1 without requiring service token for every request.

🟡 No API rate limiting

No evidence of rate limiting on Directus or Agent Data APIs. A determined attacker could enumerate all system_issues data or stress-test the search endpoint.

🟢 Docker network isolation

7 services running, all healthy. Directus uses internal URL for Nuxt SSR (http://directus:8055). Agent Data communicates via Docker network.


VII. S124 FIXES VERIFICATION

# Fix Status Evidence
1 verify_counts() = 0 ✅ PASS 0 rows WHERE status != OK
2 Orphan CAT-016 = 0 ✅ PASS code_column=entity_code, 0 orphans
3 Orphan CAT-017 = 0 ✅ PASS 31 ISS codes assigned, 0 orphans
4 Health Check CHECK 9 GREEN ✅ PASS 20 collections, DOT=112, tax=55
5 fn code_column data-driven ✅ PASS Reads from v_registry_counts
6 dot-entity-deprecate works ⚠️ BUG Function works but has RETURNING variable confusion
7 dot-entity-retire works ✅ PASS BLOCKS when dependents exist
8 truth-gate ALL PASS ✅ PASS 6/6 checks
9 coverage-inspector 0 blind spots ✅ PASS 19/19 collections
10 Collection Checklist 8 steps ✅ PASS In skills file
11 ISS auto-generate ✅ PASS ISS-0708 through ISS-0738
12 Auto-ID PG triggers ✅ PASS 15 gen_code_* functions active
13 Monitoring CHECK 9 ✅ PASS GH Actions verified

Result: 12/13 PASS, 1 has minor bug (deprecate_entity RETURNING)


TOP 10 KIẾN NGHỊ

# Kiến nghị Lý do Mức
1 Fix v_all_entity_codes VIEW — add 3 missing tables 3 managed collections invisible to entity validation 🔴
2 Fix deprecate_entity() RETURNING bug Confusing variable reuse, detail message may be wrong 🔴
3 Block public access to system_issues Leaks internal diagnostics to internet 🟡
4 Add dead links check to Health Check 119 dead links unmonitored, will accumulate 🟡
5 Resolve 119 dead links Real data integrity issues from entity_dependencies 🟡
6 Add API rate limiting (nginx level) No protection against enumeration or DoS 🟡
7 Document refresh_registry_count vs custom count functions Risk of generic overwriting custom counts 🟡
8 Clean dead code in fn_auto_label_assignment (title guard for non-title tables) Unnecessary complexity 🟢
9 Add auto-code trigger for system_issues ISS codes currently only via batch scripts 🟢
10 Plan self-healing Phase 2 707 open issues, 0 auto-resolved = detect-only 🟢

PHỤ LỤC: METRICS SNAPSHOT (Post-S124)

Metric Value Change from pre-S124
PRs total ~69 (S105-S124) +4
meta_catalog 27 entries +1 (CAT-018)
v_registry_counts 20 entries +2 (CAT-016, CAT-018)
entity_labels 1,912 +1,912 (new)
taxonomy 55 labels +55 (new)
label_rules 32 +32 (new)
DOT tools 112 +4 (truth-gate, coverage, deprecate, retire)
system_issues 707 open + 31 archived -31 archived
v_all_entity_codes 1,473 +35
Directus flows 123 active / 127 total +15 changelog
PG triggers 58 custom +22 (labels, counts, auto-code)
PG functions 32 custom +8
Health Check 9/9 GREEN +1 check
Sync gap 0 Fixed (was 12)
verify_counts mismatches 0 Maintained

Re-audit completed: 2026-03-15 by Claude Opus 4.6. No changes made — report only.