FR-080 → FR-075 交接(2026-09-11,FR-080 併入 FR-075 當日)

給 FR-075 首腦的一句話:FR-080(jedi-* 插件化第一階段)八棒+六張插隊卡全部驗收通過,整條 branch 已合進 feature/FR-075(BE 28cf59fd、套件 fast-forward 到 da25a8d)。決策者裁(2026-09-11 晚更新):「租戶隔離破洞」的資安修正歸 FR-075 這條線;FR-080 自己的收口七項仍由 FR-080 首腦做。分工見 §四。本檔是你要讀的唯一入口;FR-080 自己的 STATE/LOG 留作歷史。

§1

一、你現在拿到什麼(合併帶進來的)

類別 內容 驗收
四組套件合併 device+information-system → jedi-asset;system-config+system-menu → jedi-system-core;log-forwarding → jedi-log;participant → jedi-task-platform 八棒各自 Done,首腦親驗
空殼補實 jedi-bulletin 補成完整插件;asset/system-core 有不靠主專案就能起的 harness 親跑三行指令通過
疆界清理 四支套件對疆界外依賴改接口;通用套件去業務知識;六支轉發殼搬 monorepo archive/ 跨套件 import 120→105、零使用接口 16→6
出貨基線 CM-1655:六支標 envs=dev 的結構變更補進基線+加守門(check_env_scoped_migrations.py) 乾淨容器 init + 帶舊資料升級雙驗
今日六張插隊卡 CM-1655/1656/1657/1658/1659/1660/1661(見 §三) 全部首腦親驗,見各卡回寫

指標(基線→現在):跨套件 import 120→105/零使用接口 16→6/宿主接線 7,457→8,677/能直接裝 17→17(套件 25→21)。

§2

二、🔴 一個功能暫不可對外:切換到被指派的子租戶

CM-1661 修好了「切租戶後權限全空」,但這一修把後面更大的洞暴露出來:切到租戶 C 後,仍看得到租戶 A 的待辦任務與專案。決策者 2026-09-11 實測抓到,並定調產品模型:

垂直向下可管理(父看得到子孫),不同分支互相隔離;平台級資源(法規框架、控制項目錄、內建範本)全租戶可讀、只有原廠可寫。

現況離這個模型差多少(首腦 SQL 實證,全在 DEV,四環境一致):

層 狀態 證據
RLS 核心函式 app_tenant_allowed_for_session ✅ 已是向下涵蓋語意 鑰匙 /1/102/ 看得到 152/153/162/163/164,看不到平行的 131
平台級資源(oscal.catalogs/profiles/frameworks) ✅ 表無租戶欄、寫入限 root require_platform_admin_route
租戶級:flow_templates(is_builtin)、module_frames/detection_profiles(scope=SYSTEM) ✅ 系統範本全租戶可讀 policy 現成
租戶級:surveys/survey_folders ⚠️ 沒有平台範本旗標,租戶 1 的 8 份問卷子租戶看不到 與 flow_templates 不一致,要決策者裁要不要加 scope
專案級:compliance.projects ❌ policy 4 條寫好但 RLS 被 DISABLE 6/25 2026-06-25-align-poc-to-stg-... 第 124 行,標 envs=poc,理由只寫「以 STG 為主」
專案級:compliance.job_executions ❌ 有 tenant_id、零 policy 11,065 列
專案級:compliance.workflow_executions ❌ 只有 3 條 policy(缺 SELECT)、RLS 關 11,016 列
其餘有 tenant_id 但 RLS 沒生效的表 ❌ workflow_templates/information_systems/poams/evidence_classification_*/user_roles/user_tenants/tenant_drive_integrations/log_forwarding_settings/framework_parse_jobs 共 13 張,見下方 SQL
**三支 view 沒開 security_invoker ❌ PG16 預設用 owner(cmmgr,superuser)查底層,整個繞過 RLS** vw_user_job_queue(待辦列表)、v_user_capabilities、v_user_routes/v_role_routes
任務詳細 API GET /grc/project/<project_uid>/job/<job_uid> ❌ 收 project_uid 不驗,只用 job_uid 真 uid/全零 uuid/garbage 三種都 200 且回應 md5 相同

實證 SQL(cm_app 帳號、不設 super_admin):

set app.is_super_admin='f'; set app.user_id='17'; set app.allowed_tenant_paths='/1/999/';   -- 不存在的租戶
select count(*) from public.vw_user_job_queue where user_id=17;   -- 39(應為 0)
select count(*) from compliance.projects;                          -- 213(應為 0)

列出全部缺口的 SQL:

select n.nspname||'.'||c.relname, c.relrowsecurity, (select count(*) from pg_policy p where p.polrelid=c.oid)
from pg_class c join pg_namespace n on n.oid=c.relnamespace
where c.relkind='r' and n.nspname in ('public','compliance','survey','config','asset','oscal')
  and exists (select 1 from pg_attribute a where a.attrelid=c.oid and a.attname='tenant_id' and not a.attisdropped)
  and not c.relrowsecurity order by 1;
select c.relname, c.reloptions from pg_class c where c.relkind='v' and pg_get_userbyid(c.relowner)='cmmgr';

為什麼今天才發現:以前沒人切過租戶——切租戶要先被指派成別租戶的角色,而那個功能在 CM-1661 修好前根本不能用。修好一個洞,露出後面一個更大的。跨租戶指派 STG/POC 目前 0 筆,客戶端還沒炸。

修法方向(決策者已定語意,工量估一支 migration + 一輪驗證,不是重新設計):

  1. projects/workflow_templates/tenant_drive_integrations:policy 現成,ENABLE ROW LEVEL SECURITY 即可
  2. workflow_executions:補 SELECT policy 再開
  3. job_executions/information_systems/poams/user_roles/user_tenants/其餘:照 RLS_DESIGN.md 標準模式各補 4 條
  4. 三支 view ALTER VIEW ... SET (security_invoker = on)
  5. 問卷要不要加 scope=SYSTEM 旗標比照 flow_templates——決策者裁
  6. 任務詳細 API 補 project 歸屬驗證——與 FR-086 B1「只驗身分不驗歸屬」同型,可併
  7. 逐張表 grep 帶脈絡查跨租戶的功能(AI 儀表板統計全租戶那類)會不會被開 RLS 弄斷;無脈絡的背景任務走 session_scope else 段放行,不會斷

建議:先派一棒掃描卡(只盤不修)把 13 張表+3 view+問卷旗標逐項對照上表三層模型,列「該是哪層/現在是哪層/差什麼/誰在讀」,再開修正卡。決策者提過「當初設計時合規資源庫有踩過雷」,掃描時把 docs/changelog/2026-06-29-feat-tenant-scope-data-model-b2.md 與 2026-06-30-feat-compliance-framework-platform-write.md 讀進去,那是 6/29 定的三層模型原文。

§3

三、今日六張插隊卡(都已 Done,給你對照 hash)

卡 白話 BE 套件
CM-1655 出貨安裝包缺六項結構(含一項會讓已發照客戶寫入全 500);補進基線+守門 1fed71ac —
CM-1656 主專案直接讀被第 6 棒拆掉的問卷 ORM 屬性,儲存整筆回滾 0f56491b —
CM-1657 補值覆蓋率盤點:8 處拔關聯、0 條正在空白、9 種潛伏缺口;根因是三個補值檔覆寫 6/4/2 條而基底有 7 條 f2ed9633 —
CM-1658 檢測任務在待辦列表顯示成「一般」(第 7 棒回歸)+ 開失效問卷 500→404 e740ee1e 879473e
CM-1659 補值守衛(漏補值會叫)+三個 mixin 補到 7 條 e8e44c64 3d60145
CM-1660 填答頁補「這份問卷屬於誰」資訊區(FE,已直接進 FR-075 40291d4) 7d14a901(patch 留檔) —
CM-1661 切租戶後權限全空:C(users RLS 加本人 SELECT 例外)+A(兩支權限查詢不再 join users) 7cf63e08(reword 自 98e2122c) da25a8d

CM-1661 動了 public.users 的 SELECT policy:只放寬看、只放寬本人一列、不放寬改;migration 2026-09-11-cm1661-users-rls-self-visible.sql 已進基線,STG/POC 未套。FR-075 掃描時請知悉。

兩顆 reword:兩個 runner 共用 worktree 撞出一顆訊息對不上的 commit,合併前已 reword(98e2122c→7cf63e08、空 commit acde6b7c 已併入移除),tree 一字未動。教訓:並行派工要在 prompt 加「commit 用 git commit -- <檔名> 限定路徑」。

§4

四、分工(決策者 2026-09-11 晚定)

FR-075 只接一件:§二租戶隔離破洞(13 張表 RLS+3 支 view+問卷平台旗標+任務詳細不驗 project_uid),開在資安總表底下與 FR-086 B1 併看。

下列七項由 FR-080 首腦做,FR-075 不碰;順序是 CM-1662 arc review 先跑完、Critical 修完,才發版:

  1. M3 裁決:六條外鍵 migration 與 FR-069 以來的 envs=dev 一起審(CM-1655 已把六支改 *,M3 那條 cm1624 在其中;孤兒數三環境已查 0)
  2. 五支新套件發版推 Nexus(asset、system-core、log、task-platform、bulletin)+ jedi-iam/survey 今天也動了
  3. 發版後主專案 pyproject 改回正式 pin、拿掉 path override(目前唯一未 commit 的東西,原資料夾與 fr080 worktree 都指向 -fr080 monorepo)
  4. test repo 假綠 e2e my-tasks-detection.steps.js:323 改斷言
  5. git worktree remove 兩個 -fr080(BE、套件),拆之前先把 pyproject override 改指回原資料夾 monorepo(兩邊現在同 commit)
  6. 文件:SPEC 頁(writing-feature-specs)、母卡 CM-1619 改 Done、design.md 狀態改「已落地」、記憶同步 docs/claude/memory/
  7. release note 要寫:切子租戶功能已可用但隔離未修,修好前不對客戶開放
  8. CM-1662 arc review(五 agent,只讀不修)——已開,docs/review/2026-09-11-fr080-arc-review.md
§5

五、環境現況

項目 值
BE 8000 / SocketIO 8002 從原資料夾 compliance-manager-be(FR-075,含合併)起;.env 已補 PORT=8000
venv 原資料夾 venv 已 poetry install,14 支 editable 指向 jedi-python-package-fr080;六支舊殼 wheel 已 uninstall(留著會與新套件重複宣告表,SQLAlchemy 炸)
套件 monorepo 原資料夾與 -fr080 同 commit da25a8d;原資料夾根目錄多六個 untracked 舊套件目錄(dist/coverage 殘留,git 不追蹤,可刪)
DEV DB CM-1655 六支+CM-1661 一支已套;出貨基線庫同;STG/POC 未動
123 的 agent 已從 STG re-enroll 到 DEV(10.8.0.10:8000),STG 那列變死資料要手動撤銷;還原 re-enroll --endpoint https://192.168.50.188
備份 tag backup/FR-075-pre-merge-fr080(BE 86af8892、套件 8aa6f06)、backup/FR-080-pre-reword(3cce33d6)
未 push BE FR-075 領先 origin 20 顆、套件 FR-075 領先 34 顆、FE FR-075 領先 1 顆
§6

六、接手自檢

  1. FR-080 現在在哪?(答:已合進 FR-075,BE 28cf59fd;FR-080 branch 與 worktree 留著等拆)
  2. 為什麼切子租戶不能給客戶用?(答:projects/job_executions RLS 沒生效+view 繞 RLS,切過去看得到別分支)
  3. 決策者定的租戶模型?(答:垂直向下、分支隔離、平台級全讀原廠寫)
  4. 哪些要等令?(答:push、發版、pin 還原、拆 worktree、母卡 Done、STG/POC 套 migration)