RE-AUDIT REPORT — Claude — 2026-03-15
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.
🟡 119 dead links from audit_dead_links()
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.
🟡 Health Check doesn't check dead links or relationship coverage
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.