KB-71E2

WF Procedure Index — Read-only PG Source Survey (2026-06-23)

15 min read Revision 1
workflow-manageprocedure-indexread-onlysurveypg-read-pginventory-source-map2026-06-23

WF Procedure Index — Read-only PG Source Survey

Path: knowledge/dev/laws-new/workflow-manage/reports/wf-procedure-index-readonly-survey-2026-06-23.md Status: READ-ONLY SURVEY · Non-authorizing · 0 PG writes · 0 DDL · 0 DML Date: 2026-06-23 · DB surveyed: directus (PostgreSQL) on VPS Macro: Read-only Survey + Minimal Technical Design for PG-native Procedure Index Discipline: All facts below come from SELECT-only queries against information_schema / pg_catalog / live registry tables, plus two read-only KB handbooks. Where a source could not be confirmed, it is marked UNKNOWN_SOURCE / READ_BLOCKED / NEEDS_OWNER_DECISION.


0. Method & evidence base

  • Live PG access: MCP query_pg — AST-validated, READ ONLY transaction, statement_timeout 5s, hard LIMIT 500. No write path was used or available through this channel.
  • Catalog census: pg_class / information_schema over schemas public (346 base tables, 685 views, 1 matview) and iu_core (2 tables). Restricted schemas cutter_governance, sandbox_tac are read-denied (per handbooks).
  • Row counts below are exact count(*) where stated; pg_class.reltuples estimates are flagged as est and treated as unreliable (-1 = never-ANALYZEd, not empty).
  • Grounding docs read in full: de-bai-quan-ly-quy-trinh.md (problem statement, rev21), de-bai-cai-tien.md, matrix-refactor-quick-rules.md, matrix-refactor-implementation-plan.md, dot-usage-handbook.md, collections-usage-handbook.md.

1. Headline findings

  1. The target objects do NOT exist. A catalog scan for %procedure%, wf_procedure%, wf_inventory%, %readiness%, %ingredient% found no wf_procedure, wf_procedure_ingredient, wf_procedure_link, wf_inventory_current, or wf_procedure_readiness. The Procedure Index is genuinely net-new. → safe to design without collision.
  2. "PG computes readiness from facts via views" is already idiomatic here. The same scan found 49 existing *readiness* VIEWS (v_qt001_apply_readiness_*, v_rp_*_readiness*, v_birth_*_readiness, v_process_discovery_birth_readiness_v2..v6). The pattern the problem statement asks for — a PG-computed Readiness View over declared facts — is a proven, repeated pattern on this substrate. Strong feasibility signal.
  3. A business-process store already exists but is NOT a procedure index. workflows (2 rows), workflow_steps (70), workflow_step_relations (80), workflow_categories (3) hold BPMN diagrams for human business processes (HR / export-order). They carry process_code (WF-001,WF-002), bpmn_xml, visual position_x/y. They have no assembly_layer, no ingredient/readiness concept, and only 2 demo rows. They are an adjacent, overlapping store to be indexed as an object kind (procedure:WF-001), not extended into the Procedure Index.
  4. DOT registry is the cleanest authoritative source. dot_tools = 309 rows, keyed by code, with rich metadata (trigger_type, tier, domain, operation, coverage_status, last_executed, usage_count). Ideal dot: inventory source.
  5. Approval/gate vocabulary is small and authoritative. apr_action_types = 14 rows (11 high, 1 medium, 2 low); only 3 actions have an implemented handler_ref (patch_ops_code, create_item, update_item, add_field), the other 11 are handler_ref='unimplemented'. This is a perfect approval: source AND it lets Readiness warn that an approval gate is declared-but-unbuilt.
  6. Assembly-layer metadata is sparse and procedure-blind. The only readable layer signal is meta_catalog.composition_level (atom/molecule/compound/material/product/building/meta) + a partial integer meta_catalog.layer (values 2–5, many NULL). It covers ~catalog meta-objects, not procedures. Honest default for procedures = UNMAPPED.
  7. No fuzzy/vector extension is installed. pg_extension = btree_gist, pgcrypto, plpgsql, postgres_fdw only. No pg_trgm, no vector. v0.1 fuzzy search must be native ILIKE; trigram/vector are owner-gated future steps.

2. Q1 — Source inventory map (PG-readable sources by object kind)

Authority levels: AUTHORITATIVE_CATALOG (pg_catalog/information_schema — ground truth), AUTHORITATIVE_REGISTRY (a governed table that is the SSOT for that kind), REGISTRY_CACHE (a metadata table that can lag the catalog), DECLARED (human/agent hint), UNKNOWN_SOURCE.

object_kind Authoritative PG source Cache / companion Key columns object_ref derivation Authority Freshness signal Exact size v0.1 verdict
dot public.dot_tools dot_domains(46), dot_agent_api_contract(2) code,name,file_path,status,trigger_type,tier dot:+code AUTHORITATIVE_REGISTRY date_updated,last_executed,usage_count 309 SAFE
collection (logical) public.directus_collections collection_registry(168),table_registry(21) collection collection:+name AUTHORITATIVE_REGISTRY (Directus) 143 est SAFE
collection/table (physical) information_schema.tables / pg_class collection_registry table_schema,table_name collection:schema.table AUTHORITATIVE_CATALOG DDL via migrations 346 tables SAFE
view information_schema.views / pg_class (relkind v/m) table_schema,table_name view:schema.view AUTHORITATIVE_CATALOG 685 views +1 matview SAFE
field/column information_schema.columns directus_fields(1481) table_name,column_name,data_type field:schema.table.column AUTHORITATIVE_CATALOG n/a SAFE
trigger information_schema.triggers / pg_trigger trigger_registry(107) table_name,trigger_name,function_name trigger:schema.table.trigger CATALOG (registry=cache) date_created 410 triggers SAFE (catalog)
function/procedure information_schema.routines / pg_proc routine_schema,routine_name function:schema.name AUTHORITATIVE_CATALOG 618 fn, 1 proc SAFE w/ overload caveat
label/tag/category public.taxonomy(55) taxonomy_facets(10),label_rules(37),entity_labels(852k) code,facet_id,parent_id,depth label:+code (facet-scoped) AUTHORITATIVE_REGISTRY (facet-ambiguous) date_created 55 PARTIAL
approval/action/gate public.apr_action_types(14) process_axis_action_vocabulary(12), approval_requests(211 instances), apr_approvals action_code,risk_level,handler_ref,status approval:+action_code AUTHORITATIVE_REGISTRY created_at,retired_at 14 SAFE
event public.event_type_registry(40) directus_flows(128),event_outbox(210k) event_domain,event_type,active event:+domain.type AUTHORITATIVE_REGISTRY created_at,active 40 SAFE
procedure (existing business) public.workflows(2) workflow_steps(70),workflow_categories(3),wf_process_candidate(19) process_code,title,status,category_id procedure:+process_code (WF-*) AUTHORITATIVE for those rows date_updated 2 PARTIAL (overlapping store)
io_contract public.dot_agent_api_contract(2) dot_code,mode,endpoint_ref io:+code AUTHORITATIVE but NARROW (executor only) created_at 2 UNKNOWN_SOURCE (general IO not modeled)
checker/validator scattered: universal_rule_registry(10),checkpoint_types(31),governance_ruleset, SQL fn_* universal_rule_run_results(130) varies checker:+code NO SINGLE REGISTRY UNKNOWN_SOURCE
report/evidence KB (agent-data) + measurement_log(42k),governance_audit_log report:+code EXTERNAL (KB) not PG UNKNOWN_SOURCE
assembly_layer (attribute, not object) meta_catalog.composition_level+.layer entity_species(40),species_collection_map(125),collection_registry.species_code layer(int),composition_level(text) n/a PARTIAL / sparse last_scan_date 169 catalog rows UNMAPPED-heavy
domain (attribute) dot_tools.domain+dot_domains(46) law_jurisdiction(43),governance_registry.domain domain n/a PARTIAL UNMAPPED-heavy
template none confirmed (iu_collection_template_registry? design_templates?) template:+code UNCONFIRMED UNKNOWN_SOURCE

2.1 Exact verified column lists (the v0.1 SAFE sources)

  • dot_toolsid, status, sort, user_created, date_created, user_updated, date_updated, code, name, name_en, description, classification, owner, script_path, token_type, category, usage_count, _dot_origin, tier, domain, operation, paired_dot, trigger_type, cron_schedule, file_path, last_executed, coverage_status, extra_metadata.
  • apr_action_typesaction_code, description, handler_ref, risk_level, status, _dot_origin, created_at, retired_at. Live vocabulary (14): high = activate_event_type, amend_law, assign_axis_owner, assign_governance_owner, authorize_build_step, delegate_authority, enact_nrm, grant_governance_exception, patch_ops_code, register_axis, register_topic_node; medium = add_field; low = create_item, update_item. Implemented handlers only: patch_ops_code→dot-apr-execute:patch_ops, create_item→…:create, update_item→…:update, add_field→…:add_field. The other 11 are unimplemented.
  • collection_registry (168) — …, code, name, collection_name, group, classification, owner, storage_role, governance_role, source_kind, migration_state, species_code, coverage_status, …. governance_role ∈ {governed, observed, excluded, locked}.
  • table_registry (21) — id, table_id, name, collection, fields(jsonb), page_url, status, module, description, _dot_origin.
  • event_type_registry (40) — event_domain, event_type, event_stream, delivery_lane, default_severity, description, active, created_at.
  • taxonomy (55) — id, code, name, name_en, facet_id, parent_id, parent_facet, depth, description, scope(array), status, replaced_by, sort, date_created, _dot_origin.
  • trigger_registry (107) — id, code, trigger_name, table_name, trigger_type, function_name, fires_on, timing, enabled, description_vi, status, date_created.
  • dot_agent_api_contract (2) — id, dot_code, candidate_code, operation, role, paired_dot, mode, fixture_ref, output_namespace, no_mutation_assertion, endpoint_ref, expected_output_schema(jsonb), verifier_schema(jsonb), error_behavior, observation_write_policy, contract_status, source_macro, created_at, notes.
  • meta_catalog (169) — …, code, name, entity_type, registry_collection, record_count, status, description, layer(int), actual_count, orphan_count, last_scan_date, atom_group, composition_level, identity_class, active_count, code_column, name_column, species_count.
  • workflows (2) — id, title, description, bpmn_xml, status, task_id, version, process_code, sort, parent_workflow_id, level, category_id, narrative, _dot_origin, date_created, date_updated.
  • workflow_steps (70) — id, workflow_id, step_key, step_type, title, description, actor_type, config(jsonb), block_id, sort_order, trigger_in_text, trigger_out_text, code, checkpoint_set_id, status, …. step_type observed ∈ {wait_for_event, human_checkpoint, condition, action, agent_call, parallel}.
  • process_axis_action_vocabulary (12) — action_code, label, description, mutates_canon, requires_confirmation, requires_president, ai_delegatable, is_checkbox, preview_required, backend_handler. (Useful secondary signal for whether an action is AI-delegatable vs president-gated.)

3. Freshness / change-signal sources already present

These are reusable for refresh strategy (do NOT build a new bus):

  • Per-row timestamps: date_created / date_updated on most Directus-backed registries; last_executed,usage_count on dot_tools; last_scan_date on meta_catalog; created_at/retired_at on apr_action_types.
  • Change logs: registry_changelog (~87k rows), schema_registry_changelog, directus_revisions (~343k), directus_activity (~350k).
  • Reconciliation snapshots: _recon_dot_fs_inventory (287), wf_fs_dot_bin_snapshot (289), wf_host_crontab_snapshot (54).
  • Event substrate: event_outbox/event_read (~210k each), event_type_registry (40). Caveat: catalog reads (information_schema/pg_class) are inherently real-time — for catalog-derived kinds freshness is always fresh; only registry-cache kinds need a freshness column.

4. Read-blocked / unknown / owner-decision items

  • cutter_governance.*, sandbox_tac.* — restricted schemas, READ_BLOCKED (not needed for v0.1).
  • General IO contract model — only dot_agent_api_contract (executor, 2 rows) exists; no general per-procedure IO contract table → io: kind = UNKNOWN_SOURCE in v0.1.
  • Checker/validator registry — scattered across universal_rule_registry, checkpoint_types, governance_ruleset, and SQL fn_*; no single SSOT → checker: = UNKNOWN_SOURCE in v0.1.
  • Template source — unconfirmed (iu_collection_template_registry vs design_templates) → NEEDS_OWNER_DECISION before template: is trusted.
  • Report/evidence — lives in agent-data KB (external to PG) → report: = UNKNOWN_SOURCE for a PG-only readiness check.
  • pg_trgm / vector — not installed; enabling is NEEDS_OWNER_DECISION (a CREATE EXTENSION, out of read-only scope).

5. What this survey authorizes

Nothing is created or mutated. This survey establishes that a 3-table + 2-view Procedure Index can be built on EXISTING, readable, authoritative sources for the SAFE object kinds (dot, collection, table, view, field, trigger, function, approval, event, existing-procedure), with UNKNOWN_SOURCE honestly carried for io/checker/report/template. The ref grammar (companion doc) is the gating design artifact. See design/minimal-technical-design-v0.1.md and reports/wf-procedure-index-go-no-go-v0.1.md.

Back to Knowledge Hub knowledge/dev/laws-new/workflow-manage/reports/wf-procedure-index-readonly-survey-2026-06-23.md