Topic Axis — 06 Axis Surface & Topic Substrate Resolver
06 — Graph-aware Axis Surface & Topic Substrate Resolver (Workstream E)
Status: LIVE (both objects)
Because the existing v_registries_pivot_surface is tree-shaped (single parent path) and therefore DAG-unsafe for topics (which may have multiple parents), two companion objects were added — read-only, additive.
v_registries_pivot_axis_surface (DAG-aware)
One row per (axis_code, node_code). The node universe is axis_assignment distinct nodes UNION all FAC-08 taxonomy nodes (currently 0, so future-ready at no cost). Exposed columns:
- axis_code, node_code, node_label
- lifecycle_status (taxonomy.status if backed, else
candidate) - parent_codes[] — union of taxonomy.parent_id-derived parent AND universal_edges (broader/narrower/related, active). Array, not a single path.
- has_multiple_parents — true when parent_codes length > 1 (the DAG signal)
- relation_type, breadcrumb (parent_codes per parent context — array, so no tree-path loss)
- count_value, child_count, assignment_count
- substrate_ref — the resolver call string for this node
- governance_status — UNGOVERNED_CANDIDATE vs TAXONOMY_BACKED
- warning_flags[] — CANDIDATE_NODE / ORPHAN_TOPIC_NODE / NO_ASSIGNMENTS / MULTI_PARENT_DAG
- grouping_status — GROUPING_REQUIRED when child_count exceeds rp_grouping_policy threshold (default 50), else OK
- pin_state — UNPINNED (registry_pin structurally available; axis pins are a future step)
Current output: 7 candidate rows, each lifecycle candidate, parent_codes empty, governance UNGOVERNED_CANDIDATE, flags {CANDIDATE_NODE, ORPHAN_TOPIC_NODE}. As edges and approvals land, the same view will show real parents, multi-parent flags, and TAXONOMY_BACKED status with no view change — the DAG logic is already in place.
fn_topic_node_substrate(node_code) → jsonb
Resolves a topic node to its full substrate, DAG-aware:
- taxonomy_node (row if the token is promoted, else null), lifecycle_status
- information_units[] + information_unit_count (live: knowledge_graph → 10 IU uuids)
- documents[], workflows[], dots_agents_events[] (target_type filtered; empty until the bridge populates them)
- governance_owner (from governance_object_ownership; null today)
- birth_record (from birth_registry; null for candidates — proving no birth was triggered)
- evidence_tags[] (the originating iu_metadata_tag uuids — full provenance)
- parent_codes[] (taxonomy parent UNION active topic edges)
Verified on TOPIC-CAND:knowledge_graph: returned 10 IUs, 10 evidence tags, null taxonomy_node, null birth_record, empty parents — exactly correct for an ungoverned candidate.
DAG guarantees
- No tree-only assumption: parents are arrays everywhere; breadcrumb is per-parent.
- No hardcoded 3 levels: depth emerges from taxonomy.parent_id chains plus edges; nothing caps it.
- No frontend math: every count/flag is computed in SQL; the UI reads values.
Reversibility
Both objects drop cleanly (function + view) with no dependency on business tables beyond read access.