WF Procedure Index — Read-only PG Source Survey (2026-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.mdStatus: 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 againstinformation_schema/pg_catalog/ live registry tables, plus two read-only KB handbooks. Where a source could not be confirmed, it is markedUNKNOWN_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_schemaover schemaspublic(346 base tables, 685 views, 1 matview) andiu_core(2 tables). Restricted schemascutter_governance,sandbox_tacare read-denied (per handbooks). - Row counts below are exact
count(*)where stated;pg_class.reltuplesestimates 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
- The target objects do NOT exist. A catalog scan for
%procedure%,wf_procedure%,wf_inventory%,%readiness%,%ingredient%found nowf_procedure,wf_procedure_ingredient,wf_procedure_link,wf_inventory_current, orwf_procedure_readiness. The Procedure Index is genuinely net-new. → safe to design without collision. - "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. - 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 carryprocess_code(WF-001,WF-002),bpmn_xml, visualposition_x/y. They have noassembly_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. - DOT registry is the cleanest authoritative source.
dot_tools= 309 rows, keyed bycode, with rich metadata (trigger_type,tier,domain,operation,coverage_status,last_executed,usage_count). Idealdot:inventory source. - Approval/gate vocabulary is small and authoritative.
apr_action_types= 14 rows (11high, 1medium, 2low); only 3 actions have an implementedhandler_ref(patch_ops_code,create_item,update_item,add_field), the other 11 arehandler_ref='unimplemented'. This is a perfectapproval:source AND it lets Readiness warn that an approval gate is declared-but-unbuilt. - 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 integermeta_catalog.layer(values 2–5, many NULL). It covers ~catalog meta-objects, not procedures. Honest default for procedures =UNMAPPED. - No fuzzy/vector extension is installed.
pg_extension=btree_gist, pgcrypto, plpgsql, postgres_fdwonly. Nopg_trgm, novector. v0.1 fuzzy search must be nativeILIKE; 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_tools—id, 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_types—action_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 areunimplemented.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_typeobserved ∈ {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_updatedon most Directus-backed registries;last_executed,usage_countondot_tools;last_scan_dateonmeta_catalog;created_at/retired_atonapr_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 alwaysfresh; 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 SQLfn_*; no single SSOT →checker:= UNKNOWN_SOURCE in v0.1. - Template source — unconfirmed (
iu_collection_template_registryvsdesign_templates) → NEEDS_OWNER_DECISION beforetemplate: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.