KB-C344

Hiện trạng hạ tầng Task/Workflow/Event trước Pilot 0 (khảo sát đọc-only)

30 min read Revision 1
kestrapilot-0khao-satread-onlytasksevent-outboxworkflows

Hiện trạng hạ tầng Task / Workflow / Event trước Pilot 0

Nhịp KHẢO SÁT, ĐỌC-ONLY. Không thiết kế, không triển khai, không tạo bảng/field/DOT/event/workflow/task. Không mutation DB, không Directus write, không deploy, không git. Hành động ghi duy nhất: chính tài liệu KB này.

Ngày khảo sát: 2026-06-29 Công cụ: query_pg (READ ONLY, role context_pack_readonly, statement_timeout 5s, LIMIT 500), đọc information_schema/pg_catalog/directus_* qua SELECT. Không dùng psql/shell. Không gọi function gây ghi.

0. Bằng chứng môi trường

SELECT current_database(), current_user, current_schema(), version();
db user schema version
directus context_pack_readonly public PostgreSQL 16.13 (Debian)
  • Trùng dự kiến (database directus, schema public). User thực tế = context_pack_readonly (role read-only chuyên dụng, KHÔNG phải directus/postgres). Tool tự chạy trong transaction READ ONLY ⇒ đảm bảo đọc-only ở tầng công cụ.
  • transaction_read_only / default_transaction_read_only: CHƯA XÁC MINH trực tiếp (current_setting bị tool chặn ngoài allowlist); nhưng mọi câu đều là SELECT và tool ép READ ONLY.

1. Tóm tắt 5 dòng — đủ/thiếu gì để chạy Pilot 0

  1. Đọc task + đổi status + lưu nháp + nhật ký: ĐỦ bằng hạ tầng đang sống — tasks đọc công khai qua Directus (Public Access read *); đổi status qua Directus Agent Policy (update *); lưu nháp vào content_* hoặc tạo task_comments. Không cần bảng mới, không cần Kestra, không cần DOT mới.
  2. Ghi "event task_completed/task_status_changed" vào event_outbox: KHÔNG có đường ghi có kiểm soát sẵn — không có event_type miền task nào active trong event_type_registry; trigger fn_event_type_validate RAISE EXCEPTION với (domain,type) lạ; event_outbox không phải Directus collection; không có DOT emit. Đường duy nhất = đăng ký event_type mới + INSERT PG = WRITE (ngoài phạm vi).
  3. Nguy cơ consumer thật bắt nhầm event pilot: KHÔNG thấy nguy cơ — cả 3 worker đã chết 33–37 ngày (queue_heartbeat stale), subscription chỉ phủ domain=system, không có subscription/worker miền task.
  4. Tách sandbox vs task thật: KHÔNG có cột chuyên trách (sandbox/environment/scope). 10 task thật đang sống; pilot phải dùng quy ước (prefix tên / task_type / _dot_origin).
  5. Workflow đang chạy: KHÔNG có bảng run/instance/execution. "Đang chạy" chỉ biểu diễn gián tiếp bằng định nghĩa workflows (bpmn_xml) + status + task_checkpoints + task_comments. Đủ cho Pilot 0 (không cần workflow). Pilot 1 dùng được workflows/workflow_steps/workflow_step_relations ở mức định nghĩa tĩnh, nhưng thiếu engine + lớp instance.

2. Bảng → vai trò → dùng lại được không

Bảng Owner Rows Directus track Vai trò Dùng lại cho Pilot 0?
tasks directus 10 ✅ 25 fields Task chính (status, content_*, assigned_to, deadline) (đọc Public; update status qua Agent Policy)
task_comments directus 75 ✅ 11 Nhật ký/nháp theo tab_scope (notes/planning/verify) (lưu nháp/kết quả)
task_checkpoints directus 9 ✅ 10 Checkpoint pass/fail theo layer CÓ (tùy chọn, lưu tiến độ)
event_outbox workflow_admin ~209,989 Append-only event log KHÔNG đường ghi kiểm soát cho task event
event_type_registry workflow_admin 52 Whitelist (domain,type) → trigger validate Chặn cứng type lạ; 0 type task active
event_read workflow_admin ~209,801 Trạng thái đã-đọc theo actor (read-model, ngoài Pilot 0)
event_pending workflow_admin 0 Hàng chờ capture Rỗng
event_subscription workflow_admin 3 Đăng ký nhận (chỉ domain=system) Không có task sub
job_queue workflow_admin 13 Hàng job (chỉ cut.*) Không liên quan task
job_dead_letter workflow_admin 0 DLQ Rỗng
queue_heartbeat workflow_admin 3 Nhịp worker (đều chết 33–37 ngày) Không worker sống
workflows directus 2 ✅ 16 Định nghĩa BPMN (có task_id) Pilot 1
workflow_steps directus 70 ✅ 19 Bước trong workflow (KHÔNG có task_id) Pilot 1
workflow_step_relations directus 80 ✅ 8 Cạnh A→B (sequence/conditional) Pilot 1
workflow_categories directus 3 ✅ 11 Phân loại Pilot 1
workflow_change_requests directus 3 ✅ 15 Đề xuất sửa quy trình Pilot 1
run/instance/execution KHÔNG TỒN TẠI

Nhóm A — tasks / task_checkpoints / task_comments

A1–A2. Tồn tại + cấu trúc tasks

Cả 3 bảng ở public, owner directus. tasks=10 rows, task_checkpoints=9, task_comments=75.

tasks (26 cột, PK id int identity-seq). Cột chính: id, name, description, status, priority, assigned_to, deadline, content_targets, content_rules, content_checklist, content_plan, content_prompt, content_reports, content_verify, content_test, sort, user_created, date_created, date_updated, checklist_version, task_type, plan_document_path, lead_ai, critic_ai, code, _dot_origin('DIRECTUS'). Không có cột generated/identity-as-identity (chỉ default nextval). status = varchar NOT NULL, không default, không CHECK (tự do).

A3. Khóa / ràng buộc / trigger

  • Ràng buộc: chỉ PRIMARY KEY trên cả 3 bảng. KHÔNG có FK, KHÔNG unique phụ, KHÔNG CHECK. ⇒ task_idtask_comments/task_checkpoints là liên kết theo quy ước, không cưỡng chế (bằng chứng: task_commentstask_id=275 trong khi tasks max id=22).
  • Trigger trên tasks (9): trg_auto_code_tasks (BEFORE INSERT → gen_code_tasks, sinh TSK-NNN), trg_before_birth_gate_tasks (BEFORE INSERT → fn_birth_gate), trg_birth_tasks/birth_trigger_tasks (AFTER INSERT → fn_birth_registry_auto), trg_desc_provenance_tasks (AFTER INSERT), trg_desc_guard_tasks (BEFORE INSERT/UPDATE OF description), trg_label_assign_tasks (AFTER INSERT/UPDATE OF name,description), trg_validate_dot_origin_tasks (BEFORE INSERT/UPDATE OF _dot_origin), trg_count_tasks (AFTER INSERT/UPDATE/DELETE/TRUNCATE STATEMENT → refresh_registry_count).

Khi UPDATE tasks.status (chỉ đụng cột status): trigger duy nhất chạy = trg_count_tasksrefresh_registry_count (đọc lại count rồi UPDATE v_registry_counts + meta_catalog). Đây là tác dụng phụ ghi bảng đếm registry, KHÔNG emit event, KHÔNG enqueue job. Các trigger UPDATE-OF-cột khác (description/name/_dot_origin) KHÔNG kích hoạt vì không sửa các cột đó.

Khi INSERT/UPDATE tasks có tự phát event/job? KHÔNG (ở tầng DB trigger). fn_birth_gate mặc định mode warning (không có key birth_gate_mode trong dot_config ⇒ không block); gen_code_tasks chỉ sinh code. Không trigger nào ghi event_outbox/job_queue. (Lưu ý: tác dụng phụ qua Directus flows — xem Nhóm D3.)

A4. Vai trò cột trong tasks

Vai trò Cột
assignee/PIC assigned_to (varchar)
actor/creator user_created
trạng thái status CÓ (active/draft/done)
deadline/due_at deadline (timestamp)
assigned_at KHÔNG CÓ
started_at KHÔNG CÓ
done_at/completed_at KHÔNG CÓ (chỉ date_updated)
nội dung task name, description, content_* (8 cột text)
payload/jsonb/result KHÔNG có jsonb; nháp kết quả dùng content_reports/content_verify/content_test/content_plan (text) CÓ (gián tiếp)
liên kết workflow KHÔNG CÓ trên tasks (chỉ chiều ngược: workflows.task_id) KHÔNG
liên kết workflow_step KHÔNG CÓ trên tasks (gián tiếp task_checkpoints.workflow_step_id) KHÔNG
liên kết IU KHÔNG CÓ
sandbox/test/scope/env/source KHÔNG có cột chuyên trách (chỉ task_type, _dot_origin) KHÔNG CÓ

SELECT status, count(*): active=7, done=2, draft=1.

A5. Mẫu tasks (đã mask)

10 dòng dữ liệu thật (không rỗng, không sandbox). Ví dụ: id1 TSK-001 "Super Session Task Manager" status=active assigned_to=claude; id21 TSK-011 status=done assigned_to=CLI; id4 TSK-002 status=draft task_type=planning. task_type ∈ {task, planning, module, regular}. _dot_origin ∈ {DIRECTUS, LEGACY|migration-s127d|..., SUSPECT:DOT|claude-desktop-s145|...}.

A6. task_checkpoints / task_comments

  • task_checkpoints (PK id; cột: task_id, checkpoint_key, layer, status, verified_by, comment_id, workflow_step_id, date_created/updated). Liên kết tasks qua task_id (bigint, không FK). Mẫu: task_id=10, checkpoint_key=schema-validated/build-passed/..., layer=L0, status=passed, verified_by=system. Dùng lưu tiến độ/checkpoint: CÓ.
  • task_comments (PK id; cột: task_id, tab_scope, agent_type, content(text NOT NULL), action, status('active'), workflow_id, bpmn_element_id, _dot_origin, user_created, date_created). Liên kết qua task_id. Mẫu: tab_scope ∈ {notes, planning, verify}, agent_type ∈ {claude, system}, content tự do. Dùng lưu nháp/comment/kết quả: CÓ.

A7. Task hiện được tạo bằng cách nào

Bằng chứng: task mới (id≥16) có _dot_origin='DIRECTUS'; task cũ LEGACY|migration; một task SUSPECT:DOT|claude-desktop. Quyền create chỉ thuộc role Agent/AI Agent (Nhóm D2). Catalog DOT không có lệnh tạo task (Nhóm E3). Có Directus flow [DOT] Tasks Create → Agent Data (đồng bộ sau tạo) và Auto-Checkpoint Layer 0 (items.create → sinh checkpoint). ⇒ Task được tạo qua Directus (REST/SDK với token Agent, hoặc app admin), KHÔNG qua DOT/trigger/job_queue. Tạo qua workflow_steps/worker: CHƯA THẤY BẰNG CHỨNG.


Nhóm B — event_outbox & event_type_registry

B1–B2. Cấu trúc + vai trò cột event_outbox (PK id uuid)

Cột: id, event_domain, event_type, event_stream, delivery_lane('immediate'), event_severity, event_subject_table, event_subject_ref, canonical_address, actor_ref, source_system, correlation_id, payload_classification('safe_metadata'), safe_payload(jsonb '{}'), occurred_at(now()), created_at(now()).

  • event_type → event_type (+ event_domain, event_stream); payload → safe_payload (jsonb); aggregate/entity id → event_subject_table+event_subject_ref; correlation_id → CÓ; trace_id / parent_span_id → KHÔNG CÓ; status xử lý / consumed_at / processed_at / retry / lease → KHÔNG CÓ trên outbox (tách sang event_read, event_pending). created/occurred → CÓ.
  • Trigger: chỉ trg_event_outbox_type_validate BEFORE INSERT → fn_event_type_validate (SECURITY DEFINER): tra (event_domain,event_type) trong registry; RAISE EXCEPTION nếu không tồn tại / inactive / lệch stream / lệch delivery_lane. KHÔNG có AFTER INSERT trigger ⇒ INSERT event KHÔNG tự sinh job/NOTIFY; tiêu thụ là polling tách rời.

B3. Dữ liệu event_outbox

  • Tổng ~209,989 dòng (reltuples; group-by đầy đủ bị timeout 5s nên không liệt kê top-20 chính xác — ghi nhận giới hạn).
  • 8 event mới nhất (theo occurred_at, tới 2026-06-29 04:00): TẤT CẢ event_domain=system, event_type ∈ {issue_opened(stream alert), issue_resolved(stream update)}, event_subject_table=system_issues, source_system=trigger, actor ∈ {dot-context-pack-verify, dot-nrm-sync, DOT-H1}. ⇒ Outbox đang sống nhưng chỉ nhận event health/system (do DOT health-check ghi qua trigger). Không có event miền task/workflow nào được phát.

B4. event_type_registry (52 rows)

Theo domain (total / active): governance 5/0, iu 16/16, mother 9/0, piece 6/6, staging 5/5, system 11/3. Không có domain task/workflow. Loại gần task/workflow nhất: chỉ 2 dòng system / process.step.startedsystem / process.step.completedcả hai active=false.

Loại cần cho Pilot Có sẵn & active?
task_assigned / task_opened / task_completed / task_status_changed KHÔNG CÓ
workflow_step_completed / workflow_advanced KHÔNG CÓ (chỉ process.step.* inactive)

B5. Consumer risk (câu hỏi quan trọng nhất)

  • event_subscription (3): agency:sysop/domain=system/stream=alert; role:health_owner/system/issue_opened/system_issues; role:health_owner/system/issue_resolved/system_issues. Tất cả mute=false nhưng chỉ phủ domain=system; KHÔNG có subscription miền task/workflow.
  • queue_heartbeat (3) — TẤT CẢ STALE: cut_pipeline_operator (external_worker, last_tick 2026-05-26, 33 ngày, ticks=1), dieu45_phase3_pilot (external_worker, 2026-05-26, 33 ngày, ticks=2), iu_outbound_default (PG_worker, 2026-05-22, 37 ngày, status=warn, ticks=0). Không worker nào tick gần đây.
  • job_queue (13) — toàn bộ job_kind = cut.* (pipeline "cut", không phải task/workflow); 7 dòng state=queued kẹt từ 2026-05-26 (worker chết), còn lại succeeded. event_pending=0, job_dead_letter=0.

Trả lời:

  • Consumer/subscription active nghe task event? KHÔNG.
  • Worker heartbeat gần đây? KHÔNG (gần nhất 33 ngày).
  • Pilot ghi event_type mới chưa có consumer → có bị worker thật bắt? KHÔNG (và thực tế không INSERT được vì validate chặn type chưa đăng ký).
  • Pilot dùng event_type sẵn có → nguy cơ worker xử lý ngoài ý muốn? Không có type miền task để mượn; nếu mượn type domain khác (iu/piece/system) thì sai ngữ nghĩa + bị validate ràng stream/lane; consumer của các domain đó cũng đang chết.

Kết luận B5: KHÔNG thấy nguy cơ event pilot bị consumer thật bắt (worker chết, không sub task, validate chặn type lạ). Bằng chứng: heartbeat 33–37 ngày + subscription chỉ system + 0 active task event_type.


Nhóm C — workflows / steps / relations (chuẩn bị Pilot 1)

C1. workflows (2 rows, PK id)

Cột: id, title, description, bpmn_xml(NOT NULL), status, task_id(nullable), version, user_created, date_created/updated, process_code, sort, parent_workflow_id, level, category_id, narrative, _dot_origin. ⇒ workflow là định nghĩa BPMN; có task_id (một workflow gắn một task) và phân cấp (parent_workflow_id, level, category_id).

  • WF-001 "Quy trình duyệt công việc": status=active, task_id=10, version=4, 10 steps, 10 relations.
  • WF-002 "Quy trình xử lý đơn hàng xuất khẩu (60 bước)": status=draft, task_id=NULL, 60 steps, 70 relations. Trigger: bộ chuẩn (auto_code gen_code_workflows, birth gate/registry, label/provenance, count, validate_dot_origin, trg_after_sync_edges_workflows). Không trigger phát event/job.

C2. workflow_steps (70 rows, PK id)

Cột: id, workflow_id, step_key, step_type, title, description, actor_type, config(jsonb), position_x/y, block_id, sort_order, date_created/updated, trigger_in_text, trigger_out_text, code, checkpoint_set_id, _dot_origin, status. KHÔNG có task_id ⇒ step không trực tiếp sinh/giữ task. step_type thực tế: wait_for_event, human_checkpoint, agent_call, condition, action. Mẫu WF-001: task_submitted(wait_for_event) → review_task(human_checkpoint) → ai_review(agent_call, actor_type=claude_ai) → approved?(condition)…

C3. workflow_step_relations (80 rows)

Cột: id, workflow_id, from_step_id, to_step_id, relation_type, condition_expression, label, sort_order. Biểu diễn A→B: CÓ — mẫu WF-001: 6→7 sequence, 7→11→12→13 sequence, 8→9 conditional "Yes", 8→10 conditional "No", 13→14 conditional "pass", 13→15 conditional "fail". Đồ thị có nhánh điều kiện.

C4. workflow_categories (3): Quản lý chung(C1-GEN), Quy trình nội bộ(C2-GEN-INT), Đề xuất thay đổi quy trình(C3-GEN-INT-WCR), đều published, có parent_id/level.

C5. workflow_change_requests (3): cột gồm change_type, title, status, position_context, suggested_block_id, dsl_diff(jsonb), approved_by, applied_at, task_id, code. Mẫu: 2× applied + 1× draft, change_type add_step/add_block, workflow_id=1, task_id=10. Dùng cho đề xuất cải tiến quy trình: CÓ (theo cột + sample).

C6. Liên kết task ↔ workflow

  • tasks có FK sang workflows/steps? KHÔNG (không cột, không FK). Chiều liên kết là ngược: workflows.task_id → tasks (một workflow mô tả quy trình của một task).
  • workflow_steps có FK/cấu hình sinh task? KHÔNG (không có task_id; config jsonb chưa khảo sát nội dung).
  • Bảng trung gian task ↔ instance/step instance? CHƯA THẤY BẰNG CHỨNG (chỉ có task_checkpoints.workflow_step_idtask_comments.workflow_id/bpmn_element_id ở mức checkpoint/comment, không phải instance).

C7. Workflow "đang chạy" biểu diễn bằng gì

Không tồn tại bảng nào trong: workflow_run(s), workflow_instance(s), workflow_execution(s), run, execution, step_instance, task_run (đã kiểm pg_class, 0 kết quả). ⇒ Không có thực thể "lần chạy". Hiện trạng biểu diễn gián tiếp bằng: định nghĩa workflows.bpmn_xml + status trên workflows/workflow_steps + task_checkpoints (pass/fail mỗi mốc) + task_comments (nhật ký WCR). KHÔNG có engine thực thi (step wait_for_event/agent_call chỉ là mô tả, không có runtime chạy chúng — worker liên quan đều chết).


Nhóm D — Directus exposure & quyền

D1. Collections được track

Track (có trong directus_collections, hidden=false): tasks(25 fields), task_comments(11), task_checkpoints(10), workflows(16), workflow_steps(19), workflow_step_relations(8), workflow_categories(11), workflow_change_requests(15). KHÔNG track (vắng hẳn khỏi Directus): event_outbox, event_type_registry, event_read, event_pending, event_subscription, job_queue, job_dead_letter, queue_heartbeat. ⇒ Toàn bộ tầng event/queue là PG-native, không expose qua Directus.

D2. Permissions (Directus 11, model policy)

Collection read create update
tasks Public Access (read *) + Agent/AI Agent/Editor Agent, AI Agent Agent Policy (update *), AI Agent Policy (update không gồm status)
task_comments Public + Agent/AI Agent/Editor Agent, AI Agent AI Agent (+ delete AI Agent)
task_checkpoints Public + Agent/AI Agent/Editor Agent, AI Agent AI Agent
workflows/steps/relations Public + Agent/AI Agent Agent/AI Agent Agent/AI Agent

Chi tiết field-level (quan trọng):

  • tasks READ: Public Access = *, row_filter {} ⇒ ẩn danh đọc đầy đủ.
  • tasks UPDATE: Agent Policy = fields * (đổi được mọi cột kể cả status); AI Agent Policy = danh sách cột KHÔNG có status/name/assigned_to/deadline/priority (chỉ content_*, task_type, lead_ai, critic_ai, checklist_version, plan_document_path). ⇒ Muốn đổi status qua Directus phải dùng token role Agent (không phải AI Agent).

Kết luận:

  • MOT live đọc task qua Directus ngay: (Public read).
  • MOT live update task qua Directus ngay: CÓ nhưng cần token role Agent (đổi status). Ẩn danh KHÔNG update được.
  • Nếu update không được: có DOT/endpoint? Đường update sẵn = Directus REST/SDK (Agent). Không cần DOT.

D3. Directus flows/hooks (128 flow tổng)

Flow active gắn tasks (đã đọc options.scope/collections):

  • Auto-Checkpoint Layer 0 — action, items.create trên tasks (chỉ khi TẠO task → sinh checkpoint). Không chạy khi update status.
  • Checklist Completion Gatefilter, items.update trên tasks. Chỉ 1 operation condition kiểm $trigger.payload.status _eq 'completed', không có op kế tiếp/reject ⇒ thực chất vô hại/no-op; thêm nữa tasks dùng status 'done' chứ không phải 'completed' ⇒ điều kiện không khớp.
  • [DOT] Tasks Update → Agent Data — action, items.update trên tasksđẩy nội dung task sang Agent Data (KB/vector) mỗi lần update (tác dụng phụ ngoài DB).
  • [WATCHDOG] tasks Update → Changelog — action, items.update trên tasks ⇒ ghi changelog.
  • [DOT] Tasks Create/Delete → Agent Data, [WATCHDOG] tasks Create/Delete → Changelog — trên create/delete.
  • Lưu ý quan trọng: AI Task Auto-DispatchAI Task Auto-Create Reviewer (active) gắn collection ai_tasks (items.update), KHÔNG phải tasks ⇒ không kích hoạt khi sửa tasks. (Tồn tại một collection riêng ai_tasks — ngoài phạm vi, CHƯA KHẢO SÁT.)
  • Flow nào gắn event_outbox? event_outbox không phải collection ⇒ không có Directus flow trên event_outbox.

⇒ Cập nhật tasks.status qua Directus kích hoạt: (DB) trg_count_tasks; (Directus) [DOT] Tasks Update → Agent Data + [WATCHDOG] tasks Update → Changelog + Checklist Completion Gate (inert). Không flow nào emit event_outbox.


Nhóm E — DOT / endpoint / function hiện có

dot_iu_command_catalog = 47 lệnh, toàn bộ thuộc miền IU/piece/collection/staging/cut-mark/health. Theo category: collection(11 mutating), health, lifecycle(14), piece(7), read(2 mutating). Hai lệnh gần event/workflow nhất:

  • dot_iu_auto_instantiate_from_event (mutating, → fn_iu_auto_instantiate_from_event) — tiêu thụ event để tạo IU, không phải emit task event.

  • dot_iu_create_workflow_from_steps (mutating, → fn_iu_compose) — compose workflow IU.

  • E1. DOT đổi tasks.status: KHÔNG CÓ (catalog không có lệnh miền task).

  • E2. DOT ghi event_outbox / emit event: KHÔNG CÓ lệnh emit tổng quát (chỉ có lệnh consume event).

  • E3. DOT tạo task: KHÔNG CÓ.

  • E4. Gate trong dot_config (16 key liên quan): description_enforcement_mode=warn (không block); không có key birth_gate_mode/app.bypass_birth_gate ⇒ birth gate mặc định warning (không chặn task INSERT); piece_event_runtime.emit_enabled=false + dry_run_only=true (emit miền piece TẮT); iu_create.gateway.mode=enforced + direct_insert_policy=block_after_guard (chặn insert thẳng bảng IU — chỉ miền IU); event.global.delivery_lane_default=immediate; event.system.poc_status=enabled. Không có gate riêng cho task/workflow. ⇒ Không gate nào cản thao tác Pilot 0 trên tasks.


Nhóm F — Kết luận đóng cho Pilot 0

Câu hỏi Đáp Bằng chứng
F1 MOT live đọc 1 task từ tasks qua Directus? tasks track + Public Access read *
F2 Đổi tasks.status qua đường ghi kiểm soát sẵn? Directus update tasks, Agent Policy = update * (AI Agent thiếu status); không CHECK chặn
F3 Lưu kết quả nháp vào cột hiện có? content_reports/verify/test/plan (text) hoặc tạo task_comments.content
F4 Ghi event task_completed/task_status_changed vào event_outbox qua đường kiểm soát sẵn? KHÔNG 0 event_type task active; fn_event_type_validate RAISE EXCEPTION; outbox không phải collection; 0 DOT emit
F5 Ghi event pilot có bị consumer/worker thật bắt nhầm? KHÔNG heartbeat 33–37 ngày stale; sub chỉ domain=system; job_queue chỉ cut.*
F6 Cần thêm field vào tasks để chạy Pilot 0? KHÔNG status + content_* + assigned_to + deadline đã đủ (started_at/done_at thiếu nhưng không bắt buộc)
F7 Phân biệt task sandbox vs thật bằng dữ liệu hiện có? KHÔNG (chỉ quy ước) Không cột sandbox/env/scope; chỉ task_type/_dot_origin/prefix tên
F8 Trigger/flow tạo tác dụng phụ khi update task? DB trg_count_tasks (refresh registry); Directus [DOT] Tasks Update→Agent Data (sync ngoài) + [WATCHDOG]→Changelog; Checklist Completion Gate inert. Không emit event.
F9 Cần đụng workflows/workflow_steps trong Pilot 0? KHÔNG Luồng task↔comment↔checkpoint độc lập workflow
F10 Pilot 0 không tạo bảng mới? Đủ tasks/task_comments/task_checkpoints
F11 Pilot 0 không cần Kestra? Toàn bộ qua Directus + PG sẵn có
F12 Miếng mới tối thiểu nếu BẮT BUỘC (chỉ liệt kê sự thật thiếu) Xem dưới

F12 — sự thật còn thiếu (KHÔNG đề xuất giải pháp):

  • Nếu Pilot 0 yêu cầu "event được ghi" đúng nghĩa event_outbox: thiếu (a) một event_type miền task đã đăng ký + active trong event_type_registry; (b) một đường ghi event_outbox có kiểm soát mà role hiện tại với tới (outbox thuộc workflow_admin, không expose Directus, không DOT emit); (c) nếu "MOT đọc lại thấy xong" phụ thuộc consumer xử lý event thì thiếu worker sống (cả 3 đang chết).
  • Nếu "event được ghi" hiểu là bản ghi nhật ký trạng thái (không nhất thiết là event_outbox): KHÔNG thiếu gì — task_comments + changelog (qua flow) đã ghi vết; date_updated/status phản ánh "xong".
  • Phụ: thiếu cột started_at/done_at/assigned_at (mốc thời gian) và cột tách sandbox — không bắt buộc cho Pilot 0 nhưng là sự thật thiếu.

Nhóm G — Kết luận đóng cho Pilot 1 (chỉ khảo sát khả năng)

Câu hỏi Đáp Bằng chứng
G1 Biểu diễn workflow 2 bước bằng workflows+workflow_steps hiện có? Đã tồn tại WF-001 (10 steps) / WF-002 (60 steps), schema đủ
G2 Quan hệ A→B trong workflow_step_relations (hoặc tương đương)? from_step_id→to_step_id, relation_type sequence/conditional, label Yes/No/pass/fail
G3 Biết Task A thuộc workflow_step nào? KHÔNG/HẠN CHẾ workflow_steps không có task_id; chỉ gián tiếp workflows.task_id (1 WF↔1 task) + task_checkpoints.workflow_step_id
G4 Khi Task A completed → xác định step kế tiếp B? CHƯA XÁC MINH "next step" có trong relations nhưng ở mức step nội bộ một WF, không phải task↔task; không engine đánh giá condition_expression
G5 Đường kiểm soát sẵn để tạo Task B? KHÔNG 0 DOT tạo task; chỉ Directus create (Agent/AI Agent); không cơ chế tự sinh task từ step
G6 Có bảng workflow_run/instance/execution? KHÔNG pg_class 0 kết quả cho mọi tên run/instance/execution/step_instance/task_run
G7 "Workflow đang chạy" hiện biểu diễn bằng gì? (sự thật) Định nghĩa workflows.bpmn_xml + status + task_checkpoints + task_comments; KHÔNG có thực thể lần-chạy
G8 Thiếu đúng miếng nào (sự thật)? (liệt kê) (1) lớp instance/run (workflow_run + step_instance/task_run); (2) liên kết task↔step ở mức instance; (3) engine/cơ chế chuyển bước khi task completed + đánh giá điều kiện

Danh sách "miếng còn thiếu" (chỉ sự thật, không giải pháp)

  1. Không có event_type miền task active trong event_type_registry (chỉ process.step.* inactive).
  2. Không có đường ghi event_outbox có kiểm soát mà role ứng dụng/Directus với tới (outbox = PG-native, owner workflow_admin, không track Directus, không DOT emit).
  3. Không có worker/consumer sống (3 heartbeat stale 33–37 ngày).
  4. Không có cột phân biệt sandbox/môi trường trên tasks.
  5. Không có cột mốc thời gian assigned_at/started_at/done_at trên tasks.
  6. Không có liên kết trực tiếp task ↔ workflow_step; không có lớp instance/run cho workflow.
  7. Không có DOT/endpoint tạo task hoặc đổi tasks.status (chỉ Directus REST/SDK).

Danh sách "nguy cơ vận hành"

  • event bị worker bắt nhầm: thấp/không (worker chết, validate chặn type lạ) — nhưng nếu một worker được hồi sinh trong lúc pilot chạy, hành vi có thể đổi (CHƯA XÁC MINH kế hoạch khởi động lại worker).
  • tác dụng phụ khi update task: [DOT] Tasks Update → Agent Data đẩy nội dung task ra Agent Data mỗi lần update (rò dữ liệu pilot sang KB/vector); [WATCHDOG] → Changelog ghi changelog; trg_count_tasks ghi v_registry_counts/meta_catalog.
  • quyền Directus: đổi status cần token role Agent (AI Agent không đủ) — nếu pilot dùng nhầm AI Agent sẽ thất bại âm thầm ở field status.
  • không tách được sandbox: task pilot lẫn 10 task thật đang sống (rủi ro nhiễu dữ liệu/registry count).
  • validate cứng: INSERT event_outbox với (domain,type) chưa đăng ký → RAISE EXCEPTION (fail-closed).
  • job kẹt: 7 job cut.* state=queued tồn từ 2026-05-26 (worker chết) — không liên quan task nhưng cho thấy queue không được phục vụ.

Danh sách "CHƯA XÁC MINH"

  • transaction_read_only/default_transaction_read_only (tool chặn current_setting).
  • Top-20 event_type theo count + tổng count chính xác event_outbox (group-by timeout 5s; dùng reltuples ~209,989).
  • Toàn bộ chuỗi operation của [DOT] Tasks Update → Agent Data (mới đọc trigger scope; hành vi "đẩy Agent Data" suy từ tên + pattern các flow → Agent Data).
  • Tồn tại token sống cho role Agent (mới xác minh permission, chưa xác minh có user/token dùng được).
  • Collection ai_tasks (riêng, có flow Auto-Dispatch/Auto-Create Reviewer) — ngoài phạm vi, chưa khảo sát cấu trúc/quan hệ với tasks.
  • Nội dung workflow_steps.config (jsonb) — chưa mở (có thể chứa cấu hình actor/agent).

Kết luận cuối cùng (dạng đóng)

  • Pilot 0 có thể làm không tạo bảng mới:
  • Pilot 0 có thể không cần Kestra:
  • Pilot 1 có thể dùng workflows/workflow_steps hiện có: — nhưng chỉ ở mức định nghĩa tĩnh (A→B có sẵn); thiếu lớp instance/run + engine để "chạy" và để nối task↔task.
  • Có rủi ro event pilot bị consumer thật bắt: KHÔNG (worker chết, sub chỉ domain system, validate chặn type lạ).
  • Có cần tạo DOT mới cho Pilot 0: KHÔNG — nếu Pilot 0 dừng ở: đọc task (Directus public) → nhập nháp (content_*/task_comments) → đổi status (Directus Agent) → đọc lại. CÓ (cần miếng mới) nếu bắt buộc phải ghi event vào event_outbox (vì thiếu event_type active + đường ghi có kiểm soát).
  • Có cần thêm field vào bảng live: KHÔNG cho luồng tối thiểu (status + content_* + comments đủ). Chỉ cần nếu muốn mốc started_at/done_at hoặc cột tách sandbox.

Hết khảo sát. Không có mutation DB / Directus write / tạo đối tượng / deploy / git. Chỉ SELECT đọc-only + tài liệu KB này.