KB-109B

IU-0 Description Policy Tiering — Runtime Investigation Report (F6 Preflight)

17 min read Revision 1
dieu44iu0description-policyf6-preflightread-only-investigationpack2b

IU-0 Description Policy Tiering — Runtime Investigation Report

  • Date: 2026-05-04
  • Mode: Read-only investigation (F6 preflight)
  • Source design: knowledge/dev/laws/dieu44-trien-khai/design/13-iu0-description-policy-tiering-and-pack2b-f6-preflight.md
  • Scope: Q1–Q11 + 5-option comparison. No DDL, no patches. HARD STOP after report.
  • Environment: VPS 38.242.240.89, container postgres, db directus (PostgreSQL).

Q1 — entity_species schema

(a) Output:

column type nullable default
id integer NO seq
sort integer YES
user_created/date_created/user_updated/date_updated
code varchar NO
species_code varchar NO
display_name varchar NO
composition_level varchar NO
management_mode varchar NO 'governed'
prefix varchar YES
description text YES
status varchar NO 'active'
_dot_origin varchar YES 'DIRECTUS'
parent_id integer YES
depth integer YES 1
kg_metadata jsonb YES '{}'::jsonb

(b) Note: No description_policy / description_tier / metadata_policy field. But there IS a kg_metadata jsonb field — could carry policy as a JSONB key without DDL. (c) Implication: Encoding policy at species-level is feasible via kg_metadata. But species ≠ collection: multiple collections may map to one species (and IU tables currently aren't in species_collection_map, so species-keyed encoding can't reach IU as-is).


Q2 — collection_registry schema

(a) Output (25 cols):

id, status, sort, user_created, date_created, user_updated, date_updated, code, name, name_en, description, classification, owner, collection_name, "group", icon, field_count, has_note, purpose, _dot_origin, storage_role, governance_role, source_kind, migration_state, species_code

(b) Note: No JSONB column. No extra_metadata, no config, no description_policy. Closest existing slot: classification varchar (currently NULL for all 11 sampled rows including IU tables) and purpose varchar. governance_role already encodes governed|observed|excluded|locked|law_artifact. (c) Implication: Option 1 (DDL description_policy) is required if encoding lives on collection_registry. Option 2 (JSONB key in extra_metadata) is NOT FEASIBLE without DDL — the column does not exist. Re-using classification would conflate semantics (its current intended use is unclear from data — all NULL).


Q3 — entity_labels, taxonomy_facets, label/facet hits

(a) Output:

entity_labels cols: id, entity_code, label_code, assigned_by, rule_id, assigned_at. taxonomy_facets cols: id, code, name, description, cardinality, max_labels_per_entity, sort, status.

Label codes matching DESC|POLICY|TIER → 0 rows.

Facets matching description|policy|tier|desc → 1 row: FAC-PROV — Description Provenance.

(b) Note: No existing label encodes policy/tier. There is one provenance facet, but it tracks PROV-DOT/PROV-AI/PROV-HUMAN, not policy tiers. The label system is per-entity_code, not per-collection — using it for collection-wide policy would require attaching one label per row, which is the wrong granularity. (c) Implication: Option 4 (label/facet) feasible without DDL but wrong granularity for collection-level policy. Would need a new facet (FAC-DESC-POLICY?) and label codes; coverage would be per entity, not per table.


(a) Output (5 keys):

key value description
description_enforcement_mode warn Đ4 §2.1 warn/block toggle
description_min_length 30 Đ3 §2.1 min length
dot_tools_description_min_length 50 per-table override
h11b_exclude_species ["system_issue"] JSON array species_code (Đ3 §2.5)
hc_heal_description_basic_autofix_enabled true H11a auto-heal gate

(b) Note: Only existing tiering mechanism = h11b_exclude_species (singular system_issue). Note plural mismatch with memory (["system_issues"] would not match — verify species_code spelling at integration time). (c) Implication: Option 5 (extend h11b_exclude_species) works without DDL but only addresses H11b side, NOT H11a, NOT the birth guard. Option 3 (new dot_config JSON array, e.g. description_policy_map) is feasible without DDL.


Q5 — v_entity_full_classification + H11a/H11b runtime findings

(a) View columns (14): entity_code, source_table, entity_type, name, description, description_length, status, domain, tier, paired_dot, governance_role, species_code, composition_level, description_provenance.

H11a findings: 0 rows (no governed entity has empty description).

H11b findings (11 source tables):

source_table h11b prov_dot no_prov_legacy
system_issues 1941 1941 0
collection_registry 149 149 0
meta_catalog 130 130 0
ui_pages 37 37 0
dot_tools 29 29 0
entity_species 23 23 0
workflow_steps 8 8 0
table_registry 7 7 0
agents 6 6 0
tasks 3 3 0
taxonomy_facets 3 3 0

(b) Note: View has tier column (already!) — possibly carries Đ43 tier-A/B/C. All H11b findings have provenance PROV-DOT (no legacy NULL). system_issues dominates — exactly the operational table the design wants tier-B-exempted. (c) Implication: A tier column already exists in the view. If v_entity_full_classification.tier source can be extended with description-tier semantics, no DDL needed. Need to inspect the view definition to see what feeds tier.


Q6 — fn_description_birth_guard source + triggers

(a) Function (key parts):

SELECT governance_role INTO _gov_role
  FROM collection_registry
  WHERE collection_name = TG_TABLE_NAME;

IF _gov_role = 'governed' THEN
  _desc := btrim(COALESCE((to_jsonb(NEW)->>'description')::text, ''));
  IF _desc = '' THEN
    -- 4-tier dot_config template lookup (level-specific → table → level → default)
    -- and fn_render_description_template(_tpl, _ctx)
  END IF;
END IF;

-- C1-C3 enforcement (warn|block):
SELECT value INTO _mode FROM dot_config WHERE key='description_enforcement_mode';
SELECT value::int INTO _min_len FROM dot_config WHERE key='description_min_length';
SELECT value::int INTO _table_min FROM dot_config WHERE key=TG_TABLE_NAME||'_description_min_length';

IF _gov_role IS NULL THEN warn-or-block "chưa đăng ký"
IF _gov_role = 'excluded' THEN RETURN NEW;
-- if desc empty/short/gaming: block iff governed && mode=block

Triggers attached (21): agents, checkpoint_sets, checkpoint_types, collection_registry, dot_tools, meta_catalog, modules, system_issues, table_registry, tasks, ui_pages, workflow_change_requests, workflow_steps, workflows, taxonomy_facets, taxonomy, entity_species, dot_domain_rules, law_jurisdiction, apr_action_types, apr_request_types. All tgenabled='O' (origin/active).

(b) Note: Function knows only governance_role. No tier knowledge. information_unit and unit_version are NOT in the trigger list yet — birth guard hasn't been attached to IU. Function uses (to_jsonb(NEW)->>'description') — works only if column exists; for IU0 (no description column on information_unit), the expression returns NULL/'' and would always trip auto-gen + min-length enforcement. (c) Implication: To honor tier semantics, fn must be extended with a tier lookup regardless of where tier lives (collection_registry column, JSONB, dot_config, label, or h11b_exclude expansion). The lookup is one extra SELECT — performance-wise all options are equivalent at function level. Tier B must short-circuit BOTH the auto-gen branch AND the C1-C3 enforcement branch.


Q7 — IU table description/profile columns

(a) Output:

information_unit ALL columns: id, canonical_address, unit_kind, lifecycle_status, content_anchor_ref, version_anchor_ref, owner_ref, parent_or_container_ref, conformance_status, identity_profile (jsonb), created_at, updated_at, created_by, updated_by, deleted_at.

unit_version desc/profile cols: content_profile (jsonb), description (text).

(b) Note: information_unit has NO description column. It carries identity_profile jsonb instead. unit_version has both description AND content_profile jsonb. This is the structural asymmetry the design flagged: IU is "structured-only," uv has free-text description plus structured profile. (c) Implication: If birth guard is attached to information_unit while it stays governed, the function will always observe empty desc → enforcement fail. Tier B exemption is functionally required, not just preference, for IU. For unit_version, tier B must skip BOTH H11a and the birth guard's min-length rule even though description exists, because content lives in content_profile.


Q8 — collection_registry JSONB/config columns

(a) Output: 0 rows (no jsonb, no extra*, no config*). (b) Note: Confirmed: extra_metadata does NOT exist on collection_registry. (Memory-line "extra_metadata is established idiom" refers to other registries, not this one.) (c) Implication: Option 2 is NOT FEASIBLE without DDL. It collapses into Option 1 (DDL a JSONB column first, then key inside).


Q9 — H11 runtime registration

(a) system_health_checks cols: code, name, jurisdiction, check_kind, executor_type, executor_ref, threshold_config (jsonb), severity_on_fail, auto_fix_action, is_active, order_index, description, _dot_origin.

H11* rows:

code name type ref threshold sev active
H11 Description Coverage sql …health-h11-description-coverage.sql {"warn_threshold":0} warn f
H11a Description Basic Missing sql …h11a-description-basic-missing.sql {"threshold":0,"comparator":"eq","result_field":"h11a_total"} critical t
H11b Description Detail Missing sql …h11b-description-detail-missing.sql {"threshold":0,"comparator":"eq","result_field":"h11b_total"} warn t

(b) Note: H11 (legacy) inactive; H11a/b active. Both are SQL-driven KB queries. threshold_config jsonb is available — could carry exclusion lists per check, but logic is in the SQL file, not the config. (c) Implication: Tier policy must reach H11a/H11b at the SQL level (the KB query files), or via a filter in v_entity_full_classification. No code change needed in Directus — only the KB query SQL.


Q10 — Directus metadata + collection_registry totals

(a) Output:

  • directus_fields exists with full schema.
  • collection_registry rows: 166 total.
  • governance_role distribution: governed 34, observed 67, excluded 60, locked 3, law_artifact 2.
  • directus_fields for collection_registry: 24 fields registered (matches PG schema 1:1).

(b) Note: Adding a new column via DDL also requires registering it in directus_fields for UI visibility — non-trivial admin work but well-trodden path. governance_role split shows scope manageable: only 34 governed collections need explicit policy (others default safely). (c) Implication: DDL+Directus registration is a known recipe; no blocker. With only 34 governed collections, a config-array (Option 3) listing tier-B tables is small/maintainable.


Q11 — Encoding without DDL — current state

(a) Output:

  • dot_config.h11b_exclude_species = ["system_issue"].
  • species_collection_map for IU tables: 0 rows (IU tables not mapped to any species).
  • (Skipped collection_registry.extra_metadata query — Q8 confirmed column absent.)

Bonus — collection_registry for relevant tables:

collection governance_role species_code classification migration_state
birth_registry governed NULL NULL unclassified
collection_registry governed NULL NULL unclassified
dot_tools governed NULL NULL pilot
entity_labels excluded NULL NULL pilot
entity_species governed NULL NULL unclassified
information_unit observed NULL NULL pilot
meta_catalog governed NULL NULL unclassified
modules governed NULL NULL unclassified
system_issues governed NULL NULL unclassified
taxonomy_facets governed NULL NULL unclassified
unit_version observed NULL NULL pilot

(b) Note: IU + unit_version currently observed (not yet governed), so birth-guard attachment hasn't fired the IU-0 problem yet — the design's concern is preflight for when they flip to governed in Pack 2B. species_code is uniformly NULL across these rows; a species-keyed mechanism (Option via entity_species.kg_metadata or h11b_exclude_species) needs species_code populated first. (c) Implication: Lowest-friction encoding TODAY is dot_config (Option 3 / extension of Option 5). Anything species-keyed needs a backfill of collection_registry.species_code first.


5-Option Comparison

# Option Feasibility DDL? Performance Maintainability
1 DDL description_policy column on collection_registry High Yes (1 col + Directus field reg) 1 lookup per trigger fire (already done) — zero added cost Highest: schema-self-documenting, queryable, RBAC via Directus, joinable in views
2 JSONB key in collection_registry.extra_metadata NOT FEASIBLE without DDL — column does not exist Yes (add JSONB col first) Same as Option 1 Lower than Option 1: no schema constraints, harder to enforce enum
3 dot_config JSON array (e.g. description_policy_map) High No One extra SELECT … WHERE key=… in trigger; jsonb @> lookup; ~negligible Medium: text key, no FK, easy to drift; works today, no Directus admin work
4 Label/facet system (entity_labels + taxonomy_facets) Medium No (data-only inserts) Per-row label scan in fn — extra subquery; manageable but slowest Low for collection-level use: wrong granularity (per-entity, not per-collection); needs new facet + per-row label maintenance
5 Extend h11b_exclude_species Partial No Same as Option 3 Lowest scope: only addresses H11b. Does NOT address H11a or birth guard. Currently uses species_code keys; IU tables unmapped to species → would need h11b_exclude_collections parallel key, drifting away from the species concept

Pragmatic ranking (read-only observation, no recommendation)

  • Option 1 is the cleanest endpoint (schema as SSOT) but requires DDL + Directus field registration + APR.
  • Option 3 is the lowest-friction starting point and doesn't require DDL; tier mapping lives in dot_config.description_policy_map JSON, and fn_description_birth_guard + H11a/H11b SQL all read from one place.
  • Option 5 alone is insufficient — the design problem spans all three surfaces (H11a, H11b, fn_description_birth_guard), and the existing key only covers H11b.
  • Option 2 is gated on DDL identical in cost to Option 1, while losing schema-level constraints — strictly dominated.
  • Option 4 is mismatched in granularity for a per-collection policy.

Cross-cutting findings (reportable, not actionable here)

  1. IU0 reality: information_unit has no description column; current fn_description_birth_guard would auto-fire empty-desc auto-gen + min-length enforcement on every INSERT once IU flips governed.
  2. H11a is currently green (0 findings). H11b is heavy (system_issues=1941, collection_registry=149) — the cleanup goal aligns with the tier B exemption proposal.
  3. v_entity_full_classification already exposes a tier column. Recommend (in next session) inspecting pg_get_viewdef('v_entity_full_classification') to learn what currently feeds tier and whether it can carry description tier without DDL.
  4. h11b_exclude_species value is ["system_issue"] (singular). Verify against entity_species.species_code spelling before relying on it.
  5. species_collection_map empty for IU tables. Any species-keyed approach (Option 5) requires backfill first.
  6. fn_description_birth_guard not yet attached to IU tables — the 21 attached triggers do not include information_unit or unit_version. Design's preflight concern is correctly anticipatory.

HARD STOP

Per investigation directive: NO patch proposed, NO Pack 2B opening, NO DDL, NO function/trigger edit, NO admin_fallback creation. Investigation closes here pending GPT/User review of this report.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/reports/iu0-description-policy-tiering-runtime-investigation-report.md