KB-78D0 rev 3

P3D Pack 1 Phase 3 — Hash Planner Birth Alignment Investigation Prompt rev3

16 min read Revision 3
p3dpack1phase3investigationhashplannerbirthspeciescompositionreadonlyrev3approved

P3D Pack 1 Phase 3 — Read-Only Hash + Planner + Birth Alignment Investigation Prompt rev3

Date: 2026-05-11 Status: rev3 — GPT patched after birth/species/composition concern; APPROVED_FOR_AGENT_DISPATCH_AFTER_USER_CONFIRMATION Mode: READ-ONLY INVESTIGATION. NO mutation. NO function patch. NO DDL. Design ref: knowledge/dev/laws/dieu44-trien-khai/design/p3d-pack1-phase3-hash-planner-compatibility-design.md New review ref: knowledge/dev/laws/dieu44-trien-khai/reviews/gpt-review-opus-birth-species-composition-concern-before-phase3-2026-05-11.md


0. Mission

Investigate blockers before any TAC→IU migration:

  1. TAC content_hash algorithm differs from IU content_hash.
  2. fn_iu_create_plan(..., unit_kind='law_unit', ...) resolves to design_doc_section.
  3. Native IU birth may enforce only Tier 0/core invariants while species/composition/DOT enrichment remain incomplete.

This is read-only investigation only. Do not fix anything.


1. Hard boundaries

  • NO DDL.
  • NO DML.
  • NO INSERT/UPDATE/DELETE.
  • NO function/trigger patch.
  • NO migration.
  • NO Directus mutation.
  • NO Qdrant/vector mutation.
  • NO Nuxt code.
  • NO DOT-119 execution.
  • NO data writes to information_unit or unit_version.
  • SELECT/source inspection only.

2. Shell setup

#!/usr/bin/env bash
set -uo pipefail
TS=$(date +%Y%m%d-%H%M%S)
LOG="/tmp/p3d-phase3-investigation-${TS}.log"
exec > >(tee -a "$LOG") 2>&1

CONTAINER="${PG_CONTAINER:-postgres}"
DB="${PG_DB:-directus}"
DBUSER="${PG_USER:-directus}"
PSQL=(docker exec -i "$CONTAINER" psql -U "$DBUSER" -d "$DB" -v ON_ERROR_STOP=1 -P pager=off)

echo "=== P3D PACK1 PHASE3 READONLY INVESTIGATION rev3 $TS ==="
echo "CONTAINER=$CONTAINER DB=$DB DBUSER=$DBUSER"

# Prove session can be read-only for investigation queries.
"${PSQL[@]}" -c "SET default_transaction_read_only = on; SHOW default_transaction_read_only;"

If PG access is blocked, upload a BLOCKED report.


3. Context verification

echo "--- C0: Phase2 schema context ---"
"${PSQL[@]}" -c "
SELECT table_name, column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_schema='public'
  AND ((table_name='information_unit' AND column_name IN ('doc_code','section_type','section_code','identity_profile','parent_or_container_ref','unit_kind','canonical_address'))
    OR (table_name='unit_version' AND column_name IN ('title','description','review_state','provenance','editor','enacted_at','updated_at','body','content_hash')))
ORDER BY table_name, column_name;"

"${PSQL[@]}" -c "SELECT count(*) AS iu_rows FROM public.information_unit; SELECT count(*) AS uv_rows FROM public.unit_version; SELECT count(*) AS tac_uv_rows FROM public.tac_unit_version;"

4. Investigation A — Hash algorithm

A1 — sha256 availability

echo "--- A1: sha256 availability ---"
"${PSQL[@]}" -c "SELECT encode(sha256(convert_to('probe','UTF8')), 'hex') AS sha256_probe;"

A2 — triggers on TAC/IU version tables

echo "--- A2: triggers on version tables ---"
"${PSQL[@]}" -c "
SELECT t.tgname, t.tgrelid::regclass AS table_name, t.tgenabled, p.proname,
       pg_get_triggerdef(t.oid) AS trigger_def
FROM pg_trigger t
JOIN pg_proc p ON p.oid=t.tgfoid
WHERE NOT t.tgisinternal
  AND t.tgrelid::regclass::text IN ('tac_unit_version','unit_version')
ORDER BY table_name, tgname;"

A3 — function source for TAC/IU hash computation

echo "--- A3: functions containing hash/content_hash ---"
"${PSQL[@]}" -c "
SELECT p.proname, pg_get_function_arguments(p.oid) AS args, pg_get_functiondef(p.oid) AS function_def
FROM pg_proc p
JOIN pg_namespace n ON n.oid=p.pronamespace
WHERE n.nspname='public'
  AND (pg_get_functiondef(p.oid) ILIKE '%content_hash%'
       OR pg_get_functiondef(p.oid) ILIKE '%sha256%'
       OR pg_get_functiondef(p.oid) ILIKE '%md5%')
ORDER BY p.proname;"

A4 — hash hypothesis tests on TAC rows

echo "--- A4: TAC hash hypothesis tests ---"
"${PSQL[@]}" <<'SQL'
WITH sample AS (
  SELECT id, content_hash, body, title, description, content_profile
  FROM public.tac_unit_version
  ORDER BY id
  LIMIT 10
), h AS (
  SELECT id, content_hash,
         length(content_hash) AS hash_len,
         encode(sha256(convert_to(body,'UTF8')), 'hex') AS sha256_body_convert,
         encode(sha256(body::bytea), 'hex') AS sha256_body_bytea,
         md5(body) AS md5_body,
         encode(sha256(convert_to(trim(body),'UTF8')), 'hex') AS sha256_trim,
         encode(sha256(convert_to(regexp_replace(body, E'\r\n', E'\n', 'g'),'UTF8')), 'hex') AS sha256_lf,
         encode(sha256(convert_to(body || coalesce(title,'') || coalesce(description,''),'UTF8')), 'hex') AS sha256_body_title_desc,
         encode(sha256(convert_to(coalesce(title,'') || body || coalesce(description,''),'UTF8')), 'hex') AS sha256_title_body_desc,
         encode(sha256(convert_to(body || coalesce(content_profile::text,''),'UTF8')), 'hex') AS sha256_body_profile,
         encode(sha256(convert_to(coalesce(title,'') || body || coalesce(description,'') || coalesce(content_profile::text,''),'UTF8')), 'hex') AS sha256_title_body_desc_profile,
         encode(sha256(convert_to(body || '|' || coalesce(title,'') || '|' || coalesce(description,'') || '|' || coalesce(content_profile::text,''),'UTF8')), 'hex') AS sha256_pipe_all
  FROM sample
)
SELECT id, hash_len,
       content_hash = md5_body AS m_md5_body,
       content_hash = sha256_body_convert AS m_sha_body_convert,
       content_hash = sha256_body_bytea AS m_sha_body_bytea,
       content_hash = sha256_trim AS m_sha_trim,
       content_hash = sha256_lf AS m_sha_lf,
       content_hash = sha256_body_title_desc AS m_sha_btd,
       content_hash = sha256_title_body_desc AS m_sha_tbd,
       content_hash = sha256_body_profile AS m_sha_bp,
       content_hash = sha256_title_body_desc_profile AS m_sha_tbdp,
       content_hash = sha256_pipe_all AS m_sha_pipe_all,
       content_hash AS actual
FROM h
ORDER BY id;
SQL

A5 — IU hash confirm

echo "--- A5: IU hash confirm ---"
"${PSQL[@]}" <<'SQL'
SELECT id,
       length(content_hash) AS hash_len,
       content_hash = encode(sha256(convert_to(body,'UTF8')), 'hex') AS match_sha256_convert,
       content_hash = encode(sha256(body::bytea), 'hex') AS match_sha256_bytea,
       content_hash = md5(body) AS match_md5,
       content_hash AS actual
FROM public.unit_version
ORDER BY id
LIMIT 10;
SQL

5. Investigation B — Planner unit_kind resolution

B1 — full function sources

echo "--- B1: fn_iu_create_plan full source ---"
"${PSQL[@]}" -c "
SELECT pg_get_functiondef(p.oid) AS fn_iu_create_plan_def
FROM pg_proc p
JOIN pg_namespace n ON n.oid=p.pronamespace
WHERE n.nspname='public' AND p.proname='fn_iu_create_plan';"

echo "--- B2: fn_iu_create full source ---"
"${PSQL[@]}" -c "
SELECT pg_get_functiondef(p.oid) AS fn_iu_create_def
FROM pg_proc p
JOIN pg_namespace n ON n.oid=p.pronamespace
WHERE n.nspname='public' AND p.proname='fn_iu_create';"

echo "--- B2b: invariant verifier source ---"
"${PSQL[@]}" -c "
SELECT pg_get_functiondef(p.oid) AS fn_iu_verify_invariants_def
FROM pg_proc p
JOIN pg_namespace n ON n.oid=p.pronamespace
WHERE n.nspname='public' AND p.proname='fn_iu_verify_invariants';"

B2 — config/vocab/lookup evidence

echo "--- B3: dot_config kind/unit/profile keys ---"
"${PSQL[@]}" -c "
SELECT key, value
FROM public.dot_config
WHERE key ILIKE '%unit_kind%'
   OR key ILIKE '%kind%'
   OR key ILIKE '%section_type%'
   OR key ILIKE '%iu_create%'
   OR key ILIKE '%species%'
   OR key ILIKE '%composition%'
ORDER BY key;"

echo "--- B4: kind/vocab/species/label candidate tables ---"
"${PSQL[@]}" -c "
SELECT c.relname AS table_name
FROM pg_class c
JOIN pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public'
  AND c.relkind IN ('r','v','m')
  AND (c.relname ILIKE '%unit_kind%'
       OR c.relname ILIKE '%kind%'
       OR c.relname ILIKE '%vocab%'
       OR c.relname ILIKE '%section_type%'
       OR c.relname ILIKE '%species%'
       OR c.relname ILIKE '%label%'
       OR c.relname ILIKE '%edge%')
ORDER BY c.relname;"

B3 — safe planner probes only

Call fn_iu_create_plan only. Do not call fn_iu_create.

echo "--- B5: planner probes for kind resolution ---"
"${PSQL[@]}" <<'SQL'
SELECT 'law_unit' AS input_kind,
       public.fn_iu_create_plan('probe/phase3-law-unit', 'law_unit', 'Phase3 title', 'Phase3 body', NULL, NULL, NULL, NULL, NULL) AS plan;
SELECT 'design_doc_section' AS input_kind,
       public.fn_iu_create_plan('probe/phase3-design-doc-section', 'design_doc_section', 'Phase3 title', 'Phase3 body', NULL, NULL, NULL, NULL, NULL) AS plan;
SELECT 'unknown_kind' AS input_kind,
       public.fn_iu_create_plan('probe/phase3-unknown-kind', 'unknown_kind', 'Phase3 title', 'Phase3 body', NULL, NULL, NULL, NULL, NULL) AS plan;
SQL

6. Investigation C — TAC vocab tables

echo "--- C1: TAC vocab tables overview ---"
"${PSQL[@]}" -c "
SELECT c.relname AS table_name
FROM pg_class c
JOIN pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public'
  AND c.relkind='r'
  AND c.relname LIKE 'tac_%vocab%'
ORDER BY c.relname;"

for tbl in tac_section_type_vocab tac_lifecycle_vocab tac_review_state_vocab tac_publication_type_vocab; do
  echo "--- ${tbl} ---"
  "${PSQL[@]}" -c "SELECT * FROM public.${tbl} ORDER BY 1 LIMIT 100;" 2>/dev/null || echo "${tbl}=NOT_FOUND_OR_SCHEMA_DIFF"
done

7. Investigation D — Birth / species / composition alignment

This section addresses the new concern: native IU birth may be core-only while species/composition/enrichment are deferred. Verify actual runtime/schema evidence.

D1 — current IU rows: identity profile, parent/container, kind

echo "--- D1: IU row profile/kind/composition sample ---"
"${PSQL[@]}" -c "
SELECT id, canonical_address, unit_kind, lifecycle_status, owner_ref,
       parent_or_container_ref,
       identity_profile,
       identity_profile ->> 'composition_role' AS composition_role,
       identity_profile ->> 'species' AS profile_species,
       identity_profile ->> 'unit_kind' AS profile_unit_kind
FROM public.information_unit
ORDER BY id
LIMIT 20;"

D2 — profile key distribution

echo "--- D2: identity_profile keys distribution ---"
"${PSQL[@]}" -c "
SELECT key, count(*)
FROM public.information_unit i,
LATERAL jsonb_object_keys(i.identity_profile) AS key
GROUP BY key
ORDER BY key;" 2>/dev/null || echo "identity_profile_not_jsonb_or_missing"

D3 — composition/edge evidence

echo "--- D3: universal_edges / contains evidence for IU ---"
"${PSQL[@]}" -c "
SELECT count(*) AS total_edges FROM public.universal_edges;" 2>/dev/null || echo "universal_edges_not_found"
"${PSQL[@]}" -c "
SELECT edge_type, count(*)
FROM public.universal_edges
WHERE edge_type ILIKE '%contain%'
   OR edge_type ILIKE '%parent%'
   OR source_ref ILIKE '%information_unit%'
   OR target_ref ILIKE '%information_unit%'
GROUP BY edge_type
ORDER BY edge_type;" 2>/dev/null || echo "universal_edges_shape_diff"

D4 — species / entity label tables and IU registration evidence

echo "--- D4: species/labels tables evidence ---"
for tbl in entity_species entity_labels species_registry birth_registry entity_enrichment collection_registry; do
  echo "--- ${tbl} existence/count/sample ---"
  "${PSQL[@]}" -c "SELECT count(*) AS count FROM public.${tbl};" 2>/dev/null || echo "${tbl}=NOT_FOUND"
  "${PSQL[@]}" -c "SELECT * FROM public.${tbl} LIMIT 5;" 2>/dev/null || true
done

# Try to find IU rows in label/species/enrichment/birth registries using canonical names.
echo "--- D4b: IU references in governance/enrichment registries ---"
for tbl in entity_labels birth_registry entity_enrichment; do
  echo "--- search ${tbl} for information_unit/unit_version/IU addresses ---"
  "${PSQL[@]}" -c "
  SELECT * FROM public.${tbl}
  WHERE to_jsonb(${tbl})::text ILIKE '%information_unit%'
     OR to_jsonb(${tbl})::text ILIKE '%unit_version%'
     OR to_jsonb(${tbl})::text ILIKE '%pilot.%'
     OR to_jsonb(${tbl})::text ILIKE '%test/p3%'
  LIMIT 20;" 2>/dev/null || echo "${tbl}=NOT_FOUND_OR_JSON_SEARCH_FAILED"
done

D5 — collection_registry / description_policy for IU tables

echo "--- D5: collection_registry for IU/TAC tables ---"
"${PSQL[@]}" -c "
SELECT *
FROM public.collection_registry
WHERE to_jsonb(collection_registry)::text ILIKE '%information_unit%'
   OR to_jsonb(collection_registry)::text ILIKE '%unit_version%'
   OR to_jsonb(collection_registry)::text ILIKE '%tac_logical_unit%'
   OR to_jsonb(collection_registry)::text ILIKE '%tac_unit_version%'
LIMIT 20;" 2>/dev/null || echo "collection_registry_shape_diff"

D6 — birth registry / trigger evidence for IU tables

echo "--- D6: birth triggers on IU/TAC tables ---"
"${PSQL[@]}" -c "
SELECT t.tgname, t.tgrelid::regclass AS table_name, t.tgenabled, p.proname, pg_get_triggerdef(t.oid) AS trigger_def
FROM pg_trigger t
JOIN pg_proc p ON p.oid=t.tgfoid
WHERE NOT t.tgisinternal
  AND (t.tgrelid::regclass::text IN ('information_unit','unit_version','tac_logical_unit','tac_unit_version')
       OR t.tgname ILIKE '%birth%')
ORDER BY table_name, tgname;"

D7 — strict invariant evidence

echo "--- D7: current invariant verification for pilot rows ---"
"${PSQL[@]}" -c "
SELECT p.proname, pg_get_function_arguments(p.oid) AS args
FROM pg_proc p
JOIN pg_namespace n ON n.oid=p.pronamespace
WHERE n.nspname='public' AND p.proname ILIKE 'fn_iu%verify%';"

# Do not assume exact signature. Print source above; if safe known signature exists in source, report it, but do not call blindly.

8. Required report

Upload report to:

knowledge/dev/laws/dieu44-trien-khai/reports/p3d-pack1-phase3-hash-planner-birth-alignment-investigation-report.md

Report must include:

phase_status=PASS|BLOCKED|PARTIAL
mode=READ_ONLY_INVESTIGATION
no_mutation_performed=true
sha256_available=true|false
hash_algorithm_tac=discovered|unknown|partial
hash_algorithm_tac_details=<summary>
hash_algorithm_iu=sha256_body|other|unknown
hash_match_hypothesis=<which test matched, if any>
planner_unit_kind_resolution=<explanation>
law_unit_status=first_class|alias|fallback|missing|bug|unknown
species_at_birth=enforced|stored|absent|unknown
composition_at_birth=enforced|stored_only|absent|unknown
parent_child_enforcement=enforced|stored_only|absent|unknown
DOT_enrichment_for_IU=active|registered_only|absent|unknown
birth_registry_for_IU=active|partial|absent|unknown
vocab_tables_found=<list>
source_objects_inspected=<list>
next_recommended_action=<specific>
log_path=<path>

Also include:

  • relevant trigger/function source object names and findings;
  • hash hypothesis match table summary;
  • planner probe summary;
  • whether migration should remain blocked pending species/composition/birth alignment.

9. Final response expected from Agent

phase3_investigation_status=PASS|PARTIAL|BLOCKED
report_path=knowledge/dev/laws/dieu44-trien-khai/reports/p3d-pack1-phase3-hash-planner-birth-alignment-investigation-report.md
hash_algorithm_tac=<summary>
hash_algorithm_iu=<summary>
law_unit_status=<summary>
species_at_birth=<summary>
composition_at_birth=<summary>
DOT_enrichment_for_IU=<summary>
no_mutation_performed=true
next_recommended_action=<short>

Return only the final response plus critical blocker notes.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/prompts/p3d-pack1-phase3-readonly-hash-planner-investigation-prompt.md