S166 Automation Audit Report
S166 — Automation Audit Report (Phần B)
Agent: Claude Code CLI | Ngày: 2026-03-26 Type: Investigation (READ-ONLY, no code changes)
B1. Contracts có tự sinh không?
NO — Manual JSON authoring required.
6 contract files in web/tests/contracts/:
registries-l1.json: 15 hardcoded checks (CAT-ALL, column headers, badges)health.json: 10 hardcoded checks (health dashboard rendering)species-matrix.json: 10 hardcoded checks (species page elements)sync-directus-vector.json: 2 checks (knowledge_documents sync)watchdog.json: 1 always-fail check (runner liveness)schema.json: Contract schema definition (not a check contract)
All checks reference specific entity codes, CSS selectors, page URLs. Adding a new collection → must create a new JSON contract manually.
B2. Runner có metadata-driven không?
PARTIALLY YES.
Two modes in scripts/integrity/main.js:
- v2.0 PG-driven (default): Queries
measurement_registrytable (pg-client.jsline 38:WHERE method=2 AND enabled=true). Auto-discovers. Adding a check = INSERT 1 PG row. - v1.0 Legacy (--legacy): Reads
web/tests/contracts/*.json. NOT auto-extending.
Conclusion: Default runner IS metadata-driven. But legacy checks (the ones that generate stale_check issues) use JSON files.
B3. PG counting có tự mở rộng không?
NO — Manual trigger creation required.
Generic counting function exists (update_record_count() from s134_m5b). But each collection needs its own trigger:
CREATE TRIGGER trg_count_[collection]
AFTER INSERT OR DELETE ON [collection]
FOR EACH STATEMENT EXECUTE FUNCTION update_record_count();
This is manual per-collection SQL. Adding a new collection requires:
CREATE TRIGGERSQLINSERT INTO meta_catalogrow- No auto-trigger creation exists.
B4. Nuxt API endpoints có tự mở rộng không?
MIXED.
| Endpoint | Auto? | Evidence |
|---|---|---|
counts.get.ts |
YES | Queries SUM(record_count) from meta_catalog where identity_class=managed. Auto-includes new entries. |
system-issues.get.ts |
NO | Hardcoded collection name system_issues. Only counts this one table. |
matrix.get.ts |
NO | Hardcoded COLLECTION_MAP with 19 collections (lines 34-54). Adding new = edit code. |
system-issues-detail.get.ts |
NO | Hardcoded SUB_CLASS_MAP with 10 sub_classes (lines 10-21). Adding new = edit code. |
B5. Tổng kết: TỰ ĐỘNG vs HARDCODE
| Thành phần | Tự động? | Chi tiết |
|---|---|---|
| PG triggers đếm | KHÔNG | Manual CREATE TRIGGER per collection |
| PG view v_registry_counts | KHÔNG | Manual entry per collection in view |
| meta_catalog | KHÔNG | Manual INSERT row per collection |
| Contracts JSON | KHÔNG | Manual JSON file authoring per check set |
| Runner v2.0 (PG-driven) | CÓ | Auto-discovers from measurement_registry |
| Runner v1.0 (Legacy JSON) | KHÔNG | Reads static JSON files |
| Nuxt API counts.get.ts | CÓ | Queries meta_catalog dynamically |
| Nuxt API system-issues | KHÔNG | Hardcoded collection name |
| Nuxt API matrix.get.ts | KHÔNG | Hardcoded COLLECTION_MAP (19 collections) |
Tóm tắt: ~30% tự động, ~70% hardcode.
Tự động: Runner v2.0 (PG measurement_registry) + counts API (meta_catalog aggregate). Hardcode: PG triggers, meta_catalog entries, contracts JSON, matrix API, system-issues APIs.
Adding new collection requires 6 manual steps:
- PG trigger (SQL)
- meta_catalog entry (Directus/DOT)
- measurement_registry row (PG — for runner v2.0)
- Contract JSON (if legacy checks needed)
- matrix.get.ts COLLECTION_MAP (if matrix page)
- dot-registry-count-refresh (initial count seed)
Recommendations for future Điều 31 evolution:
- Auto-trigger creation: A DOT tool that reads meta_catalog and creates missing counting triggers
- Dynamic COLLECTION_MAP: matrix.get.ts should read from meta_catalog instead of hardcoding
- Auto-contract generation: Generate basic contracts from meta_catalog schema
- Auto meta_catalog registration: Directus webhook on collection creation → auto-INSERT meta_catalog row