P3D Pack 1 — TAC→UI Baseline Read-Only Check — Agent Prompt (DRAFT rev3)
P3D Pack 1 — TAC→UI Baseline Read-Only Check — Agent Prompt (DRAFT rev3)
Date: 2026-05-12 Author: Opus (Claude) Rev: 3 (zero residual hardcode — DB/path/schema/expected all discovered) Mode: DRAFT — not approved for dispatch
Effort: medium.
Mission
Verify current TAC→UI runtime state. Migration safety prerequisite for 5C2.
Scope constants (GPT/User-declared only)
pilot_publication_code = 'DIEU-35'
implementation_commit = '5ce3437'
source_table_family = tac_publication, tac_logical_unit, tac_unit_version, tac_publication_member
ALL other values — DB connection, filesystem paths, URLs, column names, join paths, route directories — MUST be discovered. If not discoverable → report *_UNKNOWN. Do not guess.
Hard boundaries
No DB write. No UI change. No deploy. No migration. No DDL. No function patch. No nested dispatch.
Phase 0 — Runtime environment discovery
0A. DB connection discovery
# Discover PG container from running containers
docker ps --format '{{.Names}} {{.Image}}' | grep -i postgres
# Discover DB credentials from compose/env
find / -maxdepth 5 -name 'docker-compose*' -o -name '.env' 2>/dev/null | head -10
# Read DB_* or POSTGRES_* or DB_HOST from discovered compose/env files
grep -h 'DB_DATABASE\|DB_USER\|DB_HOST\|POSTGRES_DB\|POSTGRES_USER' <discovered_files> 2>/dev/null
Report: db_container, db_user, db_name as RESOLVED or DB_CONNECTION_UNKNOWN. If UNKNOWN → cannot run SQL phases, report BLOCKED for DB-dependent phases.
0B. Filesystem root discovery
# Discover from docker volumes/mounts
docker inspect <discovered_containers> --format '{{range .Mounts}}{{.Source}}→{{.Destination}} {{end}}' 2>/dev/null
# Discover project root from compose file location
dirname <discovered_compose_path>
# Discover from running process working directories
docker inspect <nuxt_container> --format '{{.Config.WorkingDir}}' 2>/dev/null
Report: project_root as RESOLVED path or PROJECT_ROOT_UNKNOWN.
0C. Nuxt container + source directory discovery
# Find Nuxt container
docker ps --format '{{.Names}} {{.Image}}' | grep -i nuxt
# Discover source directory within repo (not assumed /web/)
find <project_root> -maxdepth 3 -name 'nuxt.config.*' -type f 2>/dev/null
# Source dir = parent of nuxt.config.*
Report: nuxt_container, source_dir as RESOLVED or UNKNOWN.
0D. Deploy bundle discovery
# Discover from Nuxt container mounts
docker inspect <nuxt_container> --format '{{range .Mounts}}{{.Source}}→{{.Destination}} {{end}}' 2>/dev/null
# Search for .output directory
find <project_root> -maxdepth 4 -name '.output' -type d 2>/dev/null
Report: deploy_root as RESOLVED or DEPLOY_ROOT_UNKNOWN.
0E. Production origin discovery
# From nginx config
docker ps --format '{{.Names}}' | grep -i nginx
docker exec <nginx_container> cat /etc/nginx/conf.d/*.conf 2>/dev/null | grep -i server_name
# From Nuxt env
docker exec <nuxt_container> env 2>/dev/null | grep -i 'ORIGIN\|BASE_URL\|SITE_URL'
Report: production_origin as RESOLVED or PRODUCTION_ORIGIN_UNKNOWN. If UNKNOWN → HTTP checks report UNKNOWN (do not fabricate).
Phase 1 — TAC schema concept resolution
1A. Table existence verification
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name IN ('tac_publication','tac_logical_unit','tac_unit_version','tac_publication_member');
All 4 must exist. If any missing → report TABLE_MISSING, BLOCKED.
1B. Column introspection
SELECT table_name, column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name IN ('tac_publication','tac_logical_unit','tac_unit_version','tac_publication_member')
ORDER BY table_name, ordinal_position;
1C. Concept resolution
Resolve each concept from introspection results. Semantic hints are search guidance, NOT assertions — Agent must verify against actual schema:
| Concept | Table | Semantic hint | Resolution |
|---|---|---|---|
| tac_pub_pk | tac_publication | primary key / id-like column | |
| tac_pub_code | tac_publication | document code / short identifier | |
| tac_pub_version | tac_publication | version string | |
| tac_pub_lifecycle | tac_publication | lifecycle or status | |
| tac_member_pub_ref | tac_publication_member | FK to publication | |
| tac_member_uv_ref | tac_publication_member | FK to unit version | |
| tac_member_render_order | tac_publication_member | display/render ordering | |
| tac_lu_pk | tac_logical_unit | primary key | |
| tac_lu_parent_ref | tac_logical_unit | self-referential parent FK | |
| tac_lu_sort_order | tac_logical_unit | sort/order within parent | |
| tac_lu_address | tac_logical_unit | canonical/unique address | |
| tac_lu_section_type | tac_logical_unit | section type classification | |
| tac_uv_pk | tac_unit_version | primary key | |
| tac_uv_lu_ref | tac_unit_version | FK to logical unit | |
| tac_uv_title | tac_unit_version | title text | |
| tac_uv_body | tac_unit_version | body/content text |
Rule: 0 candidates = FIELD_ABSENT. 1 = RESOLVED. >1 = AMBIGUOUS_FIELD.
1D. Join path resolution (FK introspection)
SELECT tc.table_name, kcu.column_name, ccu.table_name AS foreign_table, ccu.column_name AS foreign_column
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
AND tc.table_schema = 'public'
AND tc.table_name IN ('tac_publication','tac_publication_member','tac_logical_unit','tac_unit_version');
Report resolved join graph. If ambiguous → AMBIGUOUS_JOIN_PATH.
Phase 2 — Route file discovery + TAC source confirmation
2A. Discover Laws Page route files
# Search discovered source_dir for laws-related route files
find <source_dir> -type f -name '*.vue' | xargs grep -l 'tac_publication\|laws' 2>/dev/null
If source_dir = UNKNOWN → ROUTE_FILES_UNKNOWN.
2B. TAC source confirmation
In discovered route files, scan for TAC table references (using resolved concept names where applicable):
grep -n 'tac_publication\|tac_publication_member\|tac_logical_unit\|tac_unit_version' <discovered_route_files>
2C. IU absence check
grep -n 'information_unit\|unit_version' <discovered_route_files> | grep -v 'tac_unit_version'
Expected: 0 IU references in Laws Page.
Phase 3 — HTTP reachability (conditional)
If PRODUCTION_ORIGIN_UNKNOWN → report all HTTP checks as UNKNOWN. Do not fabricate.
If origin resolved:
curl -s -o /dev/null -w "%{http_code}" <production_origin>/knowledge/laws
For pilot publication:
SELECT <tac_pub_pk> FROM tac_publication WHERE <tac_pub_code> = 'DIEU-35';
curl -s -o /dev/null -w "%{http_code}" <production_origin>/knowledge/laws/<resolved_pub_id>
Phase 4 — TAC data evidence (PATTERN ONLY)
The following are SQL patterns. Agent must compile executable SQL only after Phase 1 concept + join resolution is complete. Agent must include compiled SQL in report.
4A. Publication details
-- PATTERN: compile with resolved concepts
SELECT <tac_pub_pk>, <tac_pub_code>, <tac_pub_version>, <tac_pub_lifecycle>
FROM tac_publication
WHERE <tac_pub_code> = 'DIEU-35';
4B. Member count
-- PATTERN: compile with resolved concepts + join path
SELECT count(*)
FROM tac_publication_member pm
JOIN tac_publication p ON p.<tac_pub_pk> = pm.<tac_member_pub_ref>
WHERE p.<tac_pub_code> = 'DIEU-35';
4C. Section type diversity
-- PATTERN: compile with resolved concepts + join path
SELECT DISTINCT lu.<tac_lu_section_type>
FROM tac_logical_unit lu
JOIN tac_unit_version uv ON uv.<tac_uv_lu_ref> = lu.<tac_lu_pk>
JOIN tac_publication_member pm ON pm.<tac_member_uv_ref> = uv.<tac_uv_pk>
JOIN tac_publication p ON p.<tac_pub_pk> = pm.<tac_member_pub_ref>
WHERE p.<tac_pub_code> = 'DIEU-35'
ORDER BY 1;
Phase 5 — Baseline tree capture (PATTERN ONLY)
-- PATTERN: compile after resolution
SELECT pm.<tac_member_render_order>,
lu.<tac_lu_address>,
lu.<tac_lu_parent_ref>,
lu.<tac_lu_sort_order>,
uv.<tac_uv_title>,
length(uv.<tac_uv_body>) AS body_length
FROM tac_publication_member pm
JOIN tac_unit_version uv ON uv.<tac_uv_pk> = pm.<tac_member_uv_ref>
JOIN tac_logical_unit lu ON lu.<tac_lu_pk> = uv.<tac_uv_lu_ref>
JOIN tac_publication p ON p.<tac_pub_pk> = pm.<tac_member_pub_ref>
WHERE p.<tac_pub_code> = 'DIEU-35'
ORDER BY pm.<tac_member_render_order>;
Phase 6 — Dynamic no-hardcode audit
6A. Discover live publication codes
SELECT <tac_pub_code> FROM tac_publication;
6B. Scan for hardcoded codes
For each discovered code: scan discovered route files for literal matches.
6C. Scan for code-column comparison operators
Using resolved <tac_pub_code> concept name (NOT hardcoded "doc_code"):
grep -rn '<resolved_code_column_name>.*===\|<resolved_code_column_name>.*==' <discovered_route_files>
Report: matches per code + comparison operator matches. PASS = 0 total.
Report path
knowledge/dev/laws/dieu44-trien-khai/reports/p3d-pack1-tac-ui-baseline-readonly-check-report.md
Final response format
tac_ui_baseline_status=PASS|PARTIAL|BLOCKED
db_connection_status=RESOLVED|UNKNOWN
project_root_status=RESOLVED|UNKNOWN
nuxt_container_status=RESOLVED|UNKNOWN
source_dir_status=RESOLVED|UNKNOWN
deploy_root_status=RESOLVED|UNKNOWN
production_origin_status=RESOLVED|UNKNOWN
deploy_status=DEPLOYED|NOT_DEPLOYED|UNKNOWN
table_existence_verified=true|false
schema_concepts_resolved=true|false
join_paths_resolved=true|false
route_files_discovered=true|false
tac_source_confirmed=true|false|UNKNOWN
iu_references_in_laws_page=true|false|UNKNOWN
laws_listing_reachable=true|false|UNKNOWN
dieu35_reader_reachable=true|false|UNKNOWN
dieu35_member_count=<N>
dieu35_section_type_count=<N>
baseline_tree_captured=true|false
hardcode_scan_dynamic=true|false
no_hardcode_audit_pass=true|false|UNKNOWN
report_path=<above>
no_mutation_performed=true
next_recommended_action=GPT_REVIEW_BASELINE_THEN_5C2_REV3
TAC→UI Baseline | DRAFT rev3 | Zero residual hardcode | 2026-05-12