KB-41FD

03 UI Source Discovery + Deploy Handoff

4 min read Revision 1

03 · UI Source Discovery and Deploy Handoff (Phase B)

Discovery (live, via ssh)

  • Nuxt source: /opt/incomex/docker/nuxt-repo/web (git repo, branch main ahead 17 / behind 13 of origin).
  • Existing Process-Axis-relevant routes already scaffolded:
    • web/pages/knowledge/registries-pivot/index.vue (12 KB)
    • web/server/api/registries-pivot/{node,rows,summary}.get.ts
  • Live serving: nginx serves the built static output at /opt/incomex/deploys/nuxt-output/public (last built 2026-05-31). Backups: nuxt-output.prev, nuxt-output.bak.20260531-rp-final, etc.
  • Write perms: source is writable as root.

Why handoff, not auto-deploy

A live frontend rebuild + static swap is outward-facing and not safely reversible in-band, the working tree is git-diverged (ahead 17/behind 13), and a failed build would degrade the knowledge UI. This exceeds "safe additive/reversible." Data layer is 100% ready (all views exist and are dual-path verified), so the UI only needs thin wiring + an operator-run build. Classified BLOCKED_UI_DEPLOY_ACCESS → packet below; no rediscovery needed.

Exact API pattern to match (from existing node.get.ts)

Routes are pure pass-throughs: const rows = await rpQuery('SELECT * FROM <view/fn>($1)', [arg]); return {source, generated_at, ...}. The Process Axis routes need no fn — they read the verified views directly.

Handoff — files to add

Server routes under web/server/api/process-axis/:

// canon-gate.get.ts
export default defineEventHandler(async () => ({
  source: 'pg:v_rp_process_canon_gate_summary',
  generated_at: new Date().toISOString(),
  rows: await rpQuery('SELECT * FROM v_rp_process_canon_gate_summary', []),
}));
// owner-flow.get.ts  -> SELECT * FROM v_process_axis_owner_decision_flow ORDER BY sort_rank
// candidates.get.ts  -> SELECT * FROM wf_process_candidate ORDER BY candidate_code
// candidate-detail.get.ts (code param) -> wf_process_candidate + wf_process_candidate_member
// residual.get.ts    -> SELECT * FROM v_workflow_residual_evidence_hardening_v4
// remediation.get.ts -> SELECT * FROM v_workflow_orphan_remediation_v2
// owner-gate-queue.get.ts -> SELECT * FROM v_process_axis_owner_gate_queue
// birth-queue.get.ts -> SELECT * FROM v_process_axis_birth_request_queue
// action-vocab.get.ts -> SELECT * FROM v_wf_candidate_action_handler_status
// action-preview.post.ts -> SELECT fn_wf_candidate_action_execute($1,$2,$3,$4,$5,true)  (preview only; never preview=false from UI)

Page web/pages/knowledge/registries-pivot/process-axis.vue — tabs:

  1. Official vs Candidate coverage (canon-gate: official 0/453 vs candidate_visible 69)
  2. Candidate list + detail + component graph (candidates + members)
  3. Remediation v2 + Residual v4
  4. Owner gate queue + Birth request queue
  5. Action panel — renders action-vocab; buttons call action-preview only; gate_class drives a disabled/locked badge for FAIL_CLOSED_* actions. No checkboxes, no direct mutation, no Nuxt-side math — all counts come from the views.

Build + deploy (operator)

cd /opt/incomex/docker/nuxt-repo/web
npm run build            # nuxt build -> .output
cp -r /opt/incomex/deploys/nuxt-output /opt/incomex/deploys/nuxt-output.bak.$(date +%Y%m%d%H%M%S)
rsync -a .output/public/ /opt/incomex/deploys/nuxt-output/public/
# reload nginx if needed

Rollback: restore /opt/incomex/deploys/nuxt-output.prev (or the dated backup) and reload nginx.

Blocker

UI deploy access / git divergence resolution is an operator action. No engineering blocker; the data layer + route spec are complete.

Back to Knowledge Hub knowledge/dev/reports/architecture/rp-process-axis-owner-gate-handler-ui-content-dotkg-closeout-2026-06-04/03-ui-source-discovery-deploy-or-handoff.md