本卡由 FR-116 盤點(CM-2089)帶出,唯讀查證,不改任何環境。
新客戶裝機時,稽核輪次(project_audit_rounds)與審閱標記(review_marks)這兩張表,目前實際上是「有」被套上資料庫保護(RLS)的 —— 只要客戶是拿現在的安裝包裝機。原因:安裝流程本來就會在建完 schema 之後,自動多跑一輪「套件 migration」,而這一輪就包含幫這兩張表開保護的那支腳本。
但是已經裝好的兩台機器(STG/POC)目前是「沒有」保護的,因為它們是在保護規則寫出來之前裝的機、後來也沒有升級套用過。這不是安裝流程有洞,而是「舊機器沒有跟著補課」的正常現象——只是目前沒有人去補這一動。
呼叫鏈:
scripts/installer/install.sh:1715 init_database() 先跑 guidant-db-init(MODE=init,預設值),套完 02-schema.sql(建表結構,scripts/init/init.sh:100)等基礎五段。init_apply_package_content()(scripts/installer/install.sh:1729)。init_apply_package_content()(scripts/installer/install.sh:1770-1793)用同一顆 image、改傳 GUIDANT_INIT_MODE=migrate MIGRATE_APPLY=1,再跑一次 guidant-db-init。scripts/init/migrate.sh,它會讀 scripts/sql/packages/manifest.tsv(第二輪套件 migration,見 migrate.sh:24-31 註解)逐支套用,其中就包含 packages/jedi_compliance_audit/002-compliance-audit-rls.sql(開 project_audit_rounds/review_marks 的 RLS,manifest.tsv 第 16 行)。install.sh:1772 註解原話:「新裝與升級因此走同一條路」),失敗會直接擋住不讓服務起來(install.sh:1781-1791:退出碼非 0 一律 fail)。結論:只要客戶是用含這支套件 migration 的安裝包(即 CM-1800/09-14 之後出的包)裝機,這兩張表的保護會在裝機當下自動套上,不需要人工介入。
唯讀查詢(docker exec guidant-db psql -U cmmgr -d guidant_ai,未做任何寫入):
| 檢查項 | 188 STG | 189 POC |
|---|---|---|
project_audit_rounds 開 RLS? |
❌ relrowsecurity=f |
❌ relrowsecurity=f |
review_marks 開 RLS? |
❌ relrowsecurity=f |
❌ relrowsecurity=f |
| 這兩張表有沒有任何 policy? | 0 筆 | 0 筆 |
schema_migrations 有沒有套件 migration 的紀錄? |
0 筆(packages/% 全空) |
0 筆 |
| baseline marker | __init_baseline_v1.14.0__ |
同左 |
schema_migrations 總筆數 |
141 | 141(與 188 完全一致,含同一批 2026-08-30 為止的主線 migration) |
兩台的 baseline marker 都是 v1.14.0(裝機時間約 2026-08-10 前後),而幫這兩張表開 RLS 的規則(CM-1800)是 2026-09-14 才寫出來的 —— 裝機當下這支保護規則根本還不存在,不是安裝流程漏套,是「機齡早於規則」。裝完之後也沒有任何一支 2026-09 的 migration 紀錄,代表這兩台機器自 09-14 以來沒有升級套用過任何 migration,保護規則自然沒有機會補上去。
scripts/sql/packages/ 整個目錄是 git 忽略的(.gitignore:22)——它是 build 期由 flatten_pkg_migrations.sh 從各 jedi 套件現烤出來的,本來就不是「寫進基線快照」的東西,設計上就該靠 migrate 模式在裝機/升級當下補,不是遺漏。
實際比對 scripts/init/02-schema.sql(出貨基線快照)與 11 支帶 RLS 的套件 migration 動到的 26 張表,看基線快照裡這些表當下有沒有已經開 RLS(即使套件 migration 本身不寫進快照,只要另一支主線 migration 已經把同樣的保護收斂進基線,就不算缺口):
| 表 | 基線快照已開 RLS? |
|---|---|
compliance.information_systems / public.devices(asset) |
✅ 已開 |
public.bulletins |
✅ 已開 |
compliance.project_audit_rounds / compliance.review_marks(本卡查的這兩張) |
❌ 沒開 |
compliance.detection_execution_groups 等 7 張(detection) |
✅ 已開 |
public.upload_files |
❌ 沒開 |
public.feedback_issues |
✅ 已開 |
config.tenant_license_events / config.tenant_licenses |
✅ 已開 |
compliance.agent_tasks 等 3 張(remote_agent) |
✅ 已開 |
public.system_configs |
✅ 已開 |
compliance.control_group_participants 等 6 張(task_platform participants) |
❌ 沒開(6 張全沒開) |
發現同類缺口共 2 組、8 張表:review_marks/project_audit_rounds(本卡)以及 upload_files、control_group_participants/process_participants/project_control_participants/project_group_participants/project_participants/task_assignees(task_platform 六張參與者表)。
這些不是「攤平沒補、快照該重產卻沒重產」的問題——它們本來就該靠裝機當下自動跑的 migrate 輪(見①)補上,設計上是正確的;問題只出在已經裝好、又沒升級的舊機器上(如 188/189),這一動沒人做。是否要幫舊機器補這一動(跑升級流程 / 手動套用),屬於決策者裁示範圍,本卡不建議也不動手。
install.sh --upgrade 升級流程,且這兩張表的資料有跨租戶外洩風險疑慮,可考慮由決策者裁示是否手動對這兩台跑一次 GUIDANT_INIT_MODE=migrate MIGRATE_APPLY=1(即安裝流程本來就會做的那一步,補做而已,不是新動作)。MIGRATE_APPLY=0 dry-run 檢查待套清單),是否要另外收斂進出貨流程,同樣留給決策者裁示。# 讀 code:呼叫鏈
grep -n "init_apply_package_content\|GUIDANT_INIT_MODE=migrate" scripts/installer/install.sh
sed -n '1,40p' scripts/init/migrate.sh
# 查 188 / 189(唯讀,未寫入)
ssh jedi@192.168.50.188 "docker exec guidant-db psql -U cmmgr -d guidant_ai -tAc \
\"SELECT relname, relrowsecurity FROM pg_class WHERE relname IN ('project_audit_rounds','review_marks');\""
ssh jedi@192.168.50.188 "docker exec guidant-db psql -U cmmgr -d guidant_ai -tAc \
\"SELECT tablename, policyname FROM pg_policies WHERE tablename IN ('project_audit_rounds','review_marks');\""
ssh jedi@192.168.50.188 "docker exec guidant-db psql -U cmmgr -d guidant_ai -tAc \
\"SELECT filename FROM public.schema_migrations WHERE filename LIKE '%compliance_audit%';\""
# 189 同上,主機改 192.168.50.189