KB-FF32

IU CUT Operational Pipeline — 07 Short-Command Operator Runbook

7 min read Revision 1
iu-cut-pipelinerunbookoperatorshort-commands7-stepsfn-cut-*2026-05-26

07 — Short-command operator runbook

The official operational cutting pipeline reduces to seven short calls, each producing one signal job (when queue.job_substrate.enabled=true) and one or two cut_request_transition audit rows.

Pre-requisite: workflow_admin PG role + pg_read_server_files membership (required by fn_cut_copy_to_staging for pg_read_file).

Step 0 — Lay the source on the postgres host (system-driven, one-shot)

For a KB-backed source, this is done by the harness (not the Agent):

ssh contabo "docker exec postgres bash -c 'mkdir -p /tmp/cut_zone && chown postgres:postgres /tmp/cut_zone'"
ssh contabo "docker exec postgres psql -U workflow_admin -d directus -c \"
DO \\\$\\\$
DECLARE v_oid oid;
BEGIN
  SELECT lo_from_bytea(0, convert_to(content,'UTF8')) INTO v_oid
    FROM knowledge_documents WHERE id = <KB_ID>;
  PERFORM lo_export(v_oid, '/tmp/cut_zone/<source_slug>.md');
  PERFORM lo_unlink(v_oid);
END
\\\$\\\$;\""

Source bytes never enter the Agent's tool args. For file-system-backed sources, replace the lo_export block with docker cp <local-file> postgres:/tmp/cut_zone/....

Step 1 — ADD_CUT_REQUEST

SELECT public.fn_cut_request_add(
  p_source_ref   := 'knowledge/dev/laws/<source-path>.md',
  p_source_kind  := 'kb_document',
  p_requested_by := '<actor>'
);
-- → status=requested, returns cut_request_id

Step 2 — COPY_TO_CUT_ZONE

SELECT public.fn_cut_copy_to_staging(
  p_cut_request_id := '<cut_request_id>'::uuid,
  p_source_path    := '/tmp/cut_zone/<source_slug>.md',
  p_actor          := 'system_dot_copy'
);
-- → status=copied, returns staging_file_id (=copy_staging_record_id)
-- Creates iu_core.iu_staging_record (agent_intermediate, vector_excluded=true)
-- Creates iu_core.iu_staging_payload (part_name='source_copy', payload_kind='text')

Step 3 — MARK_STAGED_FILE (Agent supplies pieces only)

SELECT public.fn_cut_mark_staged_file(
  p_cut_request_id := '<cut_request_id>'::uuid,
  p_pieces         := $pieces$[ {... N piece objects ...} ]$pieces$::jsonb,
  p_actor          := '<agent>',
  p_mark_report_md := '<optional markdown>'
);
-- → status=marked, returns manifest_staging_record_id + manifest_digest
-- Each piece needs: local_piece_id, parent_local_id (or null), sort_order, source_position,
--   canonical_address, title, section_code, section_type (in vocab.section_type.*),
--   unit_kind, piece_role, content_text (required for body validation)

The Agent does NOT pass the source text. fn_cut_mark_staged_file reads the source server-side from the source_copy payload.

Step 4 — VERIFY_MARK

SELECT public.fn_cut_verify_mark(
  p_cut_request_id  := '<cut_request_id>'::uuid,
  p_approve         := true,                    -- or false to reject
  p_approval_doc_id := '<KB-path-to-approval-doc>',
  p_approver        := '<approver_actor>',
  p_actor           := '<actor>'
);
-- → status=mark_verified (or mark_rejected)
-- Three-axis check runs inside fn_iu_op_verify_mark

Step 5 — CUT_APPROVED

UPDATE dot_config SET value='true' WHERE key='iu_core.composer_enabled';

SELECT public.fn_cut_apply(
  p_cut_request_id := '<cut_request_id>'::uuid,
  p_apply          := true,
  p_actor          := '<actor>'
);
-- → status=cut_done, returns cut_run_id + pieces_created (N UUIDs)
-- Durably creates N rows in public.information_unit

UPDATE dot_config SET value='false' WHERE key='iu_core.composer_enabled';

Step 6 — VERIFY_CUT

SELECT public.fn_cut_verify_cut(
  p_cut_request_id := '<cut_request_id>'::uuid,
  p_actor          := '<actor>'
);
-- → status=cut_verified (or cut_failed)
-- Three-axis check + no_vector_ok + pieces_count + problems[]

Step 7 — COMPLETE_CUT

SELECT public.fn_cut_complete(
  p_cut_request_id := '<cut_request_id>'::uuid,
  p_actor          := '<actor>'
);
-- → status=cleanup_scheduled
-- Sets cleanup_scheduled_at = now() + 15 days

Inspection views

SELECT * FROM v_cut_requests_by_status;
SELECT * FROM v_cut_request_ready_to_mark;
SELECT * FROM v_cut_request_ready_to_cut;
SELECT * FROM v_cut_request_ready_to_verify_cut;

-- Full lineage:
SELECT * FROM cut_request WHERE cut_request_id='<uuid>';
SELECT from_status, to_status, actor, occurred_at, metadata
  FROM cut_request_transition
  WHERE cut_request_id='<uuid>' ORDER BY transition_id;

-- Signal jobs:
SELECT job_id, job_kind, state, idempotency_key, created_at
  FROM job_queue
  WHERE idempotency_key LIKE 'cut.%:<cut_request_id>%'
  ORDER BY created_at;

-- Created IUs:
SELECT canonical_address, section_type, section_code, sort_order, lifecycle_status
  FROM information_unit
  WHERE canonical_address LIKE '<DIEU-XX-vY.Z>%'
  ORDER BY sort_order;

Safety contract

  • Pre-flight: pg_has_role(current_user,'workflow_admin','MEMBER') must return t.
  • The state machine refuses any out-of-order call; an error message identifies the legal next state.
  • Source path is server-side; .. in path is refused.
  • Queue payloads never contain body, vector, secret, token, password, ssn, personal_datajob_queue_payload_safe_check refuses.
  • After mission: ensure queue.job_substrate.enabled=false and iu_core.composer_enabled=false (operator manages flip-execute-restore).

Idempotency

  • fn_cut_request_add returns a new uuid each call; operator should check v_cut_requests_by_status or query by source_ref before re-requesting.
  • fn_cut_copy_to_staging uses idempotency_key cut-copy-<cut_request_id> for the staging_record; second call would conflict on UNIQUE(idempotency_key).
  • fn_cut_mark_staged_file uses cut-mark-<cut_request_id> similarly.
  • Signal job idempotency_key is <job_kind>:<cut_request_id>:<status>.

Recovery: cut_failed terminal state

If fn_cut_verify_cut returns failed, the cut_request enters cut_failed which has no legal next state (terminal until human intervention). Resolution path is operator-driven and not yet automated; carry-forward CF-3.

If fn_cut_apply errors mid-way (as happened with body required in our Phase E first attempt), the entire transaction rolls back — cut_request.status remains at mark_verified. Recovery: patch pieces via jsonb_set on iu_staging_payload, then retry.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-cut-operational-pipeline-copy-mark-verify-cut/07-short-command-runbook.md