FR-143 · 討論稿 · 2026-10-17

改善計畫逐評估目標重做

左樹只列不符合、上半稽核缺失、下半對原任務設執行人員/到期日/改善措施、送出即退回不等改完、Excel 往右延伸一列一任務、POA&M 匯出合規

現在的缺失改善頁被使用者說「國中生設計、看不懂怎麼用」:一張表列缺失、點開抽屜建風險再建矯正再建里程碑,三層巢狀,而且要等每個里程碑都打完成流程才走得下去。本案把頁面換成與稽核計畫、稽核結果同一套骨架:左樹只列判不符合的評估目標,中間一條一條看——上半段是「稽核缺失」文件表單(稽核發現、風險、稽核建議、稽核人員、查核方法、採用佐證),下半段列出這條評估目標底下的原任務,PM 對每個任務設執行人員(可多人)、到期日、改善措施,不新增任務。只排計畫、不追蹤完成,送出就推進:內稽每個任務退回第一站整條重跑、外稽進待覆核。Excel 與稽核計畫、稽核結果同一份往右延伸,一列一個任務。資料照 OSCAL POA&M 標準落點,順手修掉四個匯出不合規。請先開 雛形 點一遍再看規格。

D1~D12 全部定案(2026-10-17) 雛形三畫面+Excel 已審 動兩支套件:jedi-oscal-v2、jedi-compliance-audit 站在 FR-142(已合回 feature/FR-139)之上

D1~D12 已全部拍板,下一步寫 design.md;本稿定案後不再改寫。

狀態:定案(D1~D12 已裁,雛形與 Excel 已審) | 日期:2026-10-17 | 雛形:prototype/index.html | 範例 Excel:prototype/sample/FR-143-改善計畫範例.xlsx

路徑慣例:BE 路徑相對 compliance-manager-be/;pkg/ 代表 ~/Projects/Jedicogy/module/jedi-python-package/<套件>/<套件底線名>/;FE 路徑相對 compliance-manager-fe/。三個 repo 都在 feature/FR-139(FR-141、FR-142 已併入)。

名詞:評估目標=AO,控制項底下的檢查項目,全系統用 part_id 當鍵;POA&M=改善計畫(plan of action and milestones),OSCAL 評估層第三個文件;poam-item=一條缺失的封面,引用 finding 不複製;risk=風險;response=風險的處置計畫(表 assessment_remediations,程式稱 remediation),lifecycle 三值:recommendation 稽核建議/planned 已排計畫/completed 已完成;task=response 底下一筆工作(表 poam_milestones),type 兩值:action 要做的事/milestone 查核點;稽核次=FR-140 的概念,一輪內每次稽核一筆,各自一組 AP/AR/POA&M。

§1

變更紀錄

日期 變更 對應
2026-10-17 初稿:需求白話、現況盤點(頁面與流程)、OSCAL 核對四個落差、D1~D8、資料落點、Excel 契約、流程、拆卡草案、雛形第一輪 —
2026-10-17 決策者提問「要不要像我的稽核一樣有側邊入口」→ 新增 D9 與雛形畫面 0(改善計畫清單)、卡 6 —
2026-10-17 決策者:清單不要卡片式,資料多會撐不住,改表格(後端分頁、排序、篩選) 畫面 0 重做
2026-10-17 決策者:改善計畫不新增任務,只對原任務卡設執行人員(可多人,預設原指派人)、到期日(=里程碑)、改善措施;稽核缺失區改文件表單 雛形畫面 1 重做
2026-10-17 決策者裁:每個任務退回第一站整條重跑,到期日逐任務設定;Excel 走一列一任務+合併儲存格、計畫欄與結果欄原樣保留(往右延伸原則)、計畫欄群組收合;執行人員多人用分號;拿掉「納入改善」 → D10、Excel 契約改寫 —
2026-10-17 逐項裁決收尾:D7 不做報告只留 Excel 與 OSCAL JSON;D8 舊資料不管;D11 拿掉暫行緩解措施;D12 到期日寫進任務每一站不加欄;D1~D6、D9 改定案文字,D3 重寫、D4 併入 D10。全部定案 —
2026-10-17 棒 2、5 驗收發現規格把三站寫成三塊;決策者裁一塊對一條流程、執行人員只改第一站(design.md v1.1) —

§2

分工概述(30 秒版)

整案一句話:缺失改善頁換成左樹只列不符合評估目標、中間上半看「稽核缺失」下半對原任務逐一設執行人員、到期日、改善措施,送出就退回任務重跑不等改完;側邊選單多一個「改善計畫」入口;Excel 與稽核計畫、稽核結果同一份往右延伸、一列一任務;POA&M 資料照 OSCAL 標準落點並修匯出不合規。

棒 做什麼 產出 完成怎麼判定(決策者親手做什麼、看到什麼)
0 雛形 純前端假資料:入口清單、改善計畫頁、匯入預覽、範例 Excel prototype/+sample/*.xlsx 已審定版(2026-10-17)
1 套件 POA&M 修正 jedi-oscal-v2:task 匯出補期限與負責人、related-findings 剝私有鍵、POA&M 檔內嵌被引用的 finding/risk/observation、task 狀態欄退場;jedi-compliance-audit:POA&M 粒度確認逐評估目標、送出守門改「每個任務三欄齊」、推進流程不再等全部完成 套件 service、匯出合規 DEV 一個有不符合的稽核次送出改善計畫後,匯出 OSCAL POA&M JSON 用官方 schema 驗證通過,檔內看得到每個 task 的到期日與執行人員
2 BE 改善計畫端點 讀(逐不符合評估目標:稽核缺失+底下的任務與原指派人)、整批存、送出(守門→鎖定→寫回任務指派人與各站到期日→退卡或進待覆核)、匯出 新 app service 檔、route、schema Swagger 存一條有三個任務的評估目標讀回一致;有任務沒填齊時送出回 412 並列出是哪個;送出後再存回 409;送出後該任務三站 due_at 都等於計畫上的到期日、指派人等於執行人員
3 FE 頁面重做 新頁殼、舊 RoundPoamView.vue 退役 FE 新檔、路由 對照雛形逐頁操作一遍,每個動作對應後端真資料
4 Excel 匯入匯出 一列一任務 workbook 讀寫(計畫欄與結果欄合併、群組收合)、執行人員比對、匯入預覽就地處理 poam_workbook_*.py、FE 預覽模式 匯出改兩列匯回,預覽標出、確認後畫面更新;寫一個不是成員的名字預覽要求處理;同一任務兩列到期日不同時標待確認
6 入口清單(D9) 側邊選單「改善計畫」+我是 PM 的待規劃輪次表格 讀模型、端點、FE 清單頁、路由 seed 用 PM 帳號登入,側邊選單點「改善計畫」看到待規劃輪次表格,換頁與排序由後端回、點列進該輪頁;用只當 auditor 的帳號登入不見此清單或為空
5 報告與 FR-140 對齊 改善計畫報告 Word/PDF(稽核紀錄+計畫表);退卡期限改讀 task 期限、覆核輪新卡期限同;到期提醒不動 poam_report_export_service.py、not_met_job_redo_service.py Word 開檔看到每條不符合的軌跡與任務表;退回的任務卡抽屜期限=計畫上的日期

依賴:1 先做 → 2、4、5 可平行 → 3、6 等 2。全部接在 feature/FR-139。

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
    P[棒 0 雛形] --> R{決策者審 D1~D12}
    R --> D[design.md 開卡]
    D --> B1[棒 1 套件 POA&M 修正]
    B1 --> B2[棒 2 BE 端點]
    B1 --> B4[棒 4 Excel]
    B1 --> B5[棒 5 報告+FR-140 對齊]
    B2 --> B3[棒 3 FE 新頁]
    F142[FR-142 已合回] -.骨架、Excel 四頁、軌跡資料.-> B3
    F142 -.-> B4
圖 1 — 棒次依賴

§3

需求

決策者原話(2026-10-16)

再來我們一樣要來重新設計 POA&M 的 UI,現在這版直接被 user 說是國中生的設計,完全看不懂要怎麼用。 比照稽核、稽核計畫的 UI 設計,有控制項/AO 導航,中央讓 user 去填寫 POA&M 的計劃,也要看到為什麼不合格,前面應該都有軌跡。 一樣要提供 Excel 匯入匯出,就用稽核的那一份往後延伸就好,前面的就不給改,後面要讓 user 把任務設定好;要注意有可能有多個任務,不過應該都是一樣,要在一定期間內把那個 AO 做完改正。 要把稽核結果有問題的控制項,讓 PM 去設定要怎麼改善以及時間,只需要提供計畫就好,不需要等他改完——因為現在好像要等他改完,我們的流程就變成是交給下一輪。 內稽的話就是去重新設定當輪的任務,給出時間以及怎麼修正,提交後要發通知給他們重做。外部稽核的話就是會影響下一輪的起始控制項跟任務內容,流程會一樣,只是只需要注意剩的不合格的項目。 一樣都要符合 OSCAL 的規範,不要硬塞東西。 流程跟建議欄位我們應該都沒問題,不過你還是確認一下好了。

白話複述(決策者 2026-10-16 確認,2026-10-17 逐項裁決後更新)

  1. 頁面換成與稽核計畫、稽核結果同一套:左樹只列這次判不符合的評估目標;中間一次一條,上半「稽核缺失」文件表單(稽核發現、風險等級、風險說明、稽核建議、稽核人員、查核方法、採用佐證),下半列出這條評估目標底下的原任務。
  2. 不新增任務:PM 對每個任務設執行人員(可多人,預設原指派人)、到期日(就是里程碑)、改善措施(可帶入稽核建議)。有缺失的評估目標底下的任務都要退回,沒有納不納入。
  3. 只填計畫不追蹤:沒有「完成打勾」,改沒改由下一次稽核判定。
  4. 送出=流程往下走:守門看「每個任務三欄齊」,不再等任務全部完成;送出後鎖定。
  5. 內稽送出後:每個任務退回第一站整條重跑(證據上傳重做、主管與顧問再檢核一次),指派人改成執行人員、每一站到期日都是計畫上的日期、改善措施寫成系統留言、發通知。
  6. 外稽送出後:母輪進待覆核,覆核輪只建不符合項的任務、從第一站開始、到期日與指派人照計畫。
  7. 側邊選單多一個「改善計畫」,表格列出我是 PM 的輪次,預設看待規劃的。
  8. Excel 與稽核計畫、稽核結果同一份往右延伸:計畫欄、結果欄灰底唯讀並合併,一列一個任務,填執行人員(分號分隔)、到期日、改善措施。
  9. 匯出只有 Excel 與 OSCAL JSON;舊資料不管;資料照 OSCAL POA&M 標準落點,不自創欄位。

新畫面長什麼樣

雛形 prototype/index.html 三個畫面:

  • 畫面 0 入口清單(my-poams.html):側邊選單「改善計畫」,表格一列一輪,欄位見 D9;狀態頁籤帶筆數、預設「待規劃」;點列進該輪。
  • 畫面 1 改善計畫頁(poam-authoring.html):
    • 左樹:控制族群 → 控制項 → 評估目標,只列判不符合的;燈號是「規劃好沒」(綠已規劃、橘部分規劃、紅未規劃)。篩選:全部/未規劃。
    • 點控制項=控制項總覽:控制項結論(固定不符合)、「已規劃 k/n 項」、相關任務與目前執行人員;下方逐不符合評估目標列風險等級、稽核發現、計畫狀態、到期日,點列進入。
    • 點評估目標=評估目標頁,由上往下:①稽核缺失文件表單(左標籤右內容:稽核發現、風險等級、風險說明、稽核建議、稽核人員、查核方法、採用佐證、其他佐證);②改善計畫:這條評估目標底下的每個任務一塊(任務名、原指派人、狀態),每塊填執行人員*(chip 多選,預設原指派人)、到期日*、改善措施*(「帶入稽核建議」一鍵抄入)。同一任務也對到別條評估目標時顯示提示,執行人員與到期日共用。
    • 頁首:匯入 Excel、匯出(Excel/OSCAL JSON)、儲存、送出改善計畫;統計列:不符合控制項、不符合評估目標、已規劃、未規劃、退回任務、最晚到期。
    • 送出:守門(每個任務三欄齊,缺的列出「任務名 未填:X」)→ 確認表列出每個任務、執行人員(註明相較原指派人增減)、到期日 → 送出後整份鎖定。頂部灰條可切「已送出」與「外部稽核」看差異。
  • 畫面 2 匯入預覽(import-preview.html):同一畫面的預覽模式,黃框=會更新、紅框=待確認(執行人員不是專案成員、到期日格式不對),就地改好才能確認。

§4

現況盤點

頁面與資料怎麼長的

元件 現況 本案動作
FE src/views/project/RoundPoamView.vue(890 行,超標) 一張 DataTable 列缺失(控制項、嚴重度、狀態、期限),點列滑出抽屜三頁籤:矯正(風險→矯正→里程碑三層巢狀、里程碑可打完成)、脈絡、證據 整頁退役,新開 RoundPoamView.vue 殼+src/components/grc/poam/ 子元件,沿用 FR-142 的 ArObjectiveTree.vue 結構
pkg/jedi-compliance-audit/app/service/poam_app_service.py(493 行) list_items/get_item 逐 item 攤 finding→risk→remediation→milestone;寫入 add_remediation/add_milestone/update_milestone(含 status=done)/delete_*;all_items_closed 當結案守門 讀寫改成「逐評估目標整批」;update_milestone 的 status 路徑退場;all_items_closed 換成 all_items_planned;超標只准新開檔
pkg/jedi-oscal-v2/app/service/poam/poam_service.py:54 generate_from_findings 稽核結案時每條 not_met finding 建一筆 poam-item,related_findings=[{finding-uuid, finding-id}] FR-142 後 finding 已是評估目標層,粒度自然對;finding-id 留 DB、匯出剝掉
pkg/jedi-compliance-audit/app/service/audit_round_pass_transitions.py:99 _close_on_pass all_items_closed 不成立就 412 GRC_POAM_NOT_ALL_CLOSED——這就是「要等改完」的卡點 改成 all_items_planned(每 item 至少一筆 planned response 且每 task 有期限與負責人)
BE app/flow_control/service/not_met_job_redo_service.py(126 行) 內部缺失改善站推進時退卡:earliest_milestone_dates 取每控制項最早 target_date 當 due_at、寫重做紀錄、發通知 讀取改到評估目標層(卡對 ao_part_id),其餘不動
pkg/jedi-compliance-audit/.../audit_round_app_service.py:543 launch_reverify 覆核輪新卡 due_at=母輪最後稽核次 POA&M 里程碑日期 同上,改讀 task 期限,其餘不動
表 oscal.poams/poam_items/assessment_risks/assessment_remediations/poam_milestones 三層結構齊全;poam_milestones 有 task_type、assignee_user_id、assignee_org_unit_id、target_date、status、completed_at 不加表;status/completed_at 停用(不刪)
pkg/jedi-oscal-v2/app/service/io/oscal_io_service.py:1584 _milestone_to_task_json、:1600 _export_poam 見下節四個落差 棒 1 修

流程現況(FR-140 已做好的,本案只改觸發點)

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
    ar[內部稽核結案<br/>FR-142] -- 有不符合 --> ipoam[內部改善計畫<br/>本案頁面]
    ipoam -- "送出(守門:計畫齊全)<br/>舊:全部里程碑完成" --> redo[退卡重做<br/>原卡、原人、期限=計畫]
    redo --> plan2[第 2 次內稽計畫<br/>只剩不符合項]
    ear[外部稽核結案] -- 有不符合 --> epoam[外部改善計畫<br/>本案頁面]
    epoam -- "送出(同守門)" --> pend[本輪待覆核]
    pend -. 發起覆核 .-> rev[覆核輪新卡<br/>期限=計畫]
圖 2 — 一輪內的改善計畫在哪裡;本案改的是兩個「推進條件」

兩處推進條件現在都呼叫 all_items_closed,改成「計畫齊全」後其餘機制(退卡、通知、縮範圍、覆核輪 clone)照舊。

OSCAL 核對:對的與要修的

對照官方 oscal_poam_schema.json(v1.2.2)核過,決策者 2026-10-16 已點頭:

對的:

  • response.lifecycle 三值 recommendation/planned/completed,稽核建議與 PM 計畫分別落 recommendation/planned,完全對應。
  • risk → response → task 三層巢狀是官方正規結構,表 assessment_risks → assessment_remediations → poam_milestones 對得上。
  • poam-item 只當封面、related-findings 引用 finding 不複製,符合官方設計。
  • 流程(退卡、覆核)不歸 OSCAL 管。

要修的四處(棒 1):

# 落差 官方落點 怎麼修
1 task 匯出沒帶期限與負責人(_milestone_to_task_json 只寫 uuid/type/title/description/props/links) task.timing.within-date-range.end(或 on-date.date);task.responsible-roles[].party-uuids 匯出補兩欄;負責人要對到 SSP metadata.parties 的 party-uuid(既有 _enrich_party_user_org_names 的反向查法)
2 related-findings 塞私有鍵 finding-id,官方 additionalProperties:false,驗證直接失敗 只允許 finding-uuid、remarks 匯出剝掉 finding-id;DB 繼續存(查詢用)
3 POA&M 檔內 findings[]/risks[]/observations[] 是空的(它們掛在 AR 那邊),poam-item 的引用懸空 官方:related-findings 指向「本文件 findings 清單」 匯出時把被引用的 finding、risk(含 remediations)、observation 一併寫進 POA&M 檔(同 uuid;組裝不複製 DB)
4 task 有自創 status/completed_at 欄,官方 task 沒有 要留只能放 props 本案「不追蹤完成」,欄位停用不匯出;DB 不刪

順手對齊兩點:task type 用 action(PM 排的事)/milestone(查核點),不再全部預設 milestone;計畫送出時 risk.status 從 open 改 remediating、risk.deadline 填該項最晚期限。


§5

決策定案 D1~D12

全部由決策者 2026-10-17 拍板。每條寫定案、理由、被排除的做法。

D1 粒度=逐不符合評估目標;控制項只是分組

左樹到評估目標,每條不符合評估目標各自規劃;控制項總覽只是彙總。理由:稽核判定已是逐評估目標(FR-142),POA&M 跟著走;OSCAL poam-item 本來就對 finding。被排除:控制項層一筆(第 2 次內稽縮範圍是評估目標層,對不上)。

D2 只排計畫不追蹤完成

畫面沒有打勾、沒有進度條;改好沒有=下一次稽核判定。理由:決策者原話「只需要提供計畫就好,不需要等他改完」。poam_milestones.status/completed_at 停用不刪。被排除:保留打勾但不當守門(兩套真相)。

D3 不新增任務;對評估目標底下的原任務逐一設執行人員、到期日、改善措施;守門=每個任務三欄齊;送出後鎖定

一條評估目標底下有幾條流程就列幾塊(一條流程多站時仍是一塊,站唯讀列在塊內),有缺失就都要退回重做,沒有「納不納入」。每塊:執行人員(可多人,預設原指派人,可加減)、到期日(即里程碑)、改善措施(可一鍵帶入稽核建議)。有一個任務沒填齊就擋送出並列出哪一個缺什麼;送出後整份唯讀,要改只能下一次稽核重排。理由:決策者原話「不能新增任務,只需要對原本的任務做建議以及設定 milestone 跟執行人員」「里程碑就是對原本的任務卡設到期時間」。被排除:PM 自建改善任務清單(第一版雛形,退回);一個任務多個里程碑(第二版雛形,決策者裁太複雜且退卡後看不到真實到期日);任務可勾「不納入改善」(有缺失就都要退);送出後仍可改到期日(與退回的任務漂移)。

D4 到期日逐任務設定,寫回該任務;一個任務對到多條評估目標時共用一組執行人員與到期日

畫面上同一個任務在第二條評估目標出現時顯示「此任務同時對應 X,執行人員與到期日一併套用」,一處改兩處變。被排除:一條評估目標一個到期日套到全部任務(決策者裁逐任務);取最早或最晚(已無多里程碑,不需要)。

D5 執行人員=任務的指派人,可多人,預設原指派人,PM 可加減;改了就是改任務的指派人

畫面 chip 多選;送出確認表註明相較原指派人新增/移除了誰。理由:系統任務本來就是 task_assignees 多人;改善計畫改的人就是退回後要做的人,不另存一份。被排除:計畫上另記負責人、任務指派人不動(第一版,兩套人)。

D6 Excel=與稽核計畫、稽核結果同一份往右延伸;一列一個任務;同評估目標的灰底欄合併儲存格

欄位契約見「Excel 契約」節。理由:決策者原則「每階段往右加欄,最後是完整軌跡」(FR-142 D9 已定);一格換行 user 一定填錯、往右長一組 user 不會用,只剩一列一任務;合併儲存格讓重複資訊不干擾閱讀。被排除:一格多值換行(A);每任務往右長一組欄位(B);砍掉計畫欄只留重點(違反往右延伸原則);執行人員拆三欄。

D7 匯出兩個:改善計畫工作表(Excel)、OSCAL POA&M(JSON);不做 Word/PDF 報告

理由:OSCAL POA&M 頂層沒有文件正文欄位(AP 有 terms-and-conditions,POA&M 只有 metadata/remarks),硬放等於自創欄位;業界 POA&M 交付物就是表格(FedRAMP 官方範本是 Excel),我們的 Excel 帶完整軌跡就是那份交付物。被排除:改善計畫報告 docx/pdf(沒有正文可寫);概要頁籤(標準沒位置);併進稽核報告(已結案鎖定)。日後客戶要 Word 再從同一份資料產,另開 FR。

D8 舊資料不管

既有輪次的改善計畫不遷移、不處理,舊頁資料維持現狀。新頁只服務本案上線後結案的稽核次。被排除:寫遷移把控制項層拆到評估目標(要猜);新頁唯讀顯示舊資料(多做一套讀法)。

D9 側邊選單加「改善計畫」入口,表格列出我是專案經理的待規劃輪次

與「我的稽核」並列,名稱就叫「改善計畫」不加「我的」。表格一列一輪:專案、輪次與內外稽、狀態(待規劃/已送出/覆核中/已結束)、已規劃/不符合、退回任務數、最晚到期(30 天內橘、過期紅)、結案日、送出日。狀態頁籤帶筆數、預設「待規劃」;可篩稽核性質與標準、搜專案名;分頁、每頁筆數、排序走後端(同「待辦任務」表的 lazy 分頁)。登入者判準只看「是該專案 manager」。理由:排計畫的人是 PM,入口藏在專案三層內是「不知道怎麼用」的原因之一。被排除:卡片式清單(資料多撐不住);進度條(不好讀);併進「我的稽核」當分頁。

D10 退卡=每個任務退回第一站整條重跑

名詞:一個任務本身是一條流程,可能多站(證據上傳 → 主管檢核 → 顧問檢核)。現行內稽退卡(not_met_job_redo_service._redo_one)只把最新那一站改回進行中,三站都完成時重開的是顧問檢核,補證據的人改不到;DEV 現有 6 筆退卡紀錄全是單站流程,所以沒被測出來。定案:每個任務的第一站改回進行中、通知該任務全部指派人;後續站改回待辦,前一站完成才依序往下。改善措施照舊寫成任務上的系統留言(build_redo_comment)。實作:參考 workflow_execution_service.revert_job(目標站重開、後續站改待辦),但它帶操作者與輪次凍結守門,不適用系統退卡,另包一支只做「整條回到第一站」。外稽覆核輪產新任務同理從第一站開始。被排除:只重開最新站(現況);讓 PM 選退到哪一站。

D11 不設「暫行緩解措施」欄

OSCAL risk.mitigating-factors 匯出留空。理由:改好之前先做的臨時防護(例如先停用登入)本來就該寫進該任務的改善措施,不需要另一格;PM 看不懂這欄是什麼。被排除:評估目標層選填一格(第三版雛形)。

D12 到期日寫進該任務的每一站,不加欄位、不動 jedi-flow-engine

查證:期限欄 job_executions.due_at 已存在(FR-140),但只在每一站上,流程主表沒有;complete_job 推出下一站不帶期限;DEV 所有有期限的流程都是單站。定案:退卡時把 PM 設的到期日寫進該任務全部站的 due_at(due_at_manual=false),「我的任務」清單與抽屜讀各站期限,畫面不用改。被排除:流程主表加欄(要動套件);流程變數(字串鍵值,查詢排序不便);只壓第一站(後面站沒期限可無限拖)。


§6

資料落點

不加表。畫面欄位與 OSCAL/DB 對照:

畫面 OSCAL POA&M DB
一條不符合評估目標 poam-items[] 一筆:title/description 抄 finding、related-findings[{finding-uuid}]、related-risks[{risk-uuid}] oscal.poam_items(既有 generate_from_findings)
稽核缺失(唯讀) 從 AR 讀:finding、observation(relevant-evidence)、risk(characterizations/statement)、remediation lifecycle=recommendation;匯出時內嵌進 POA&M 檔 不重存
改善計畫(整組) risk.remediations[] 一筆 lifecycle=planned,title=「改善計畫」 oscal.assessment_remediations
一個任務的設定 response.tasks[] 一筆:type=action、title=任務名、description=改善措施、timing.on-date.date=到期日、responsible-roles[{role-id:'remediation-owner', party-uuids:[…]}]=執行人員(多人多個 uuid)、props[name=job-uid]=對應的任務流程 uid oscal.poam_milestones:task_type=action、title、description、target_date、assignee_user_id(多人:第一人進欄位,全部進 props;或改掛關聯表,棒 1 定)
送出 risk.status=remediating、risk.deadline=該項最晚到期日;poams.status=submitted;同時寫回任務:指派人、每一站 due_at、系統留言 assessment_risks.status/deadline、oscal.poams.status、compliance.task_assignees、compliance.job_executions.due_at
鎖定 無欄位;以 poams.status 判 —

官方必填核對:poam-item(title/description)、response(uuid/lifecycle/title/description)、task(uuid/type/title)、risk(uuid/title/description/statement/status)——每項畫面都有來源。執行人員要對到 party-uuid:專案參與者在 SSP metadata.parties 有對應 party(既有 matched_user_id 機制),匯出時反查;查不到的只寫 props(name=assignee)不寫 responsible-roles,不造假 uuid。mitigating-factors 留空(D11)。

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
    I[poam-item<br/>封面] -- related-findings --> F[finding<br/>FR-142 判定]
    F -- related-risks --> R[risk<br/>等級/說明/status=remediating]
    R --> REC[response<br/>lifecycle=recommendation<br/>稽核建議,唯讀]
    R --> PL[response<br/>lifecycle=planned<br/>PM 改善計畫]
    PL --> T1[task action 任務 1<br/>到期日/執行人員/改善措施]
    PL --> T2[task action 任務 2]
圖 3 — 一條不符合評估目標存成哪些 OSCAL 物件

§7

Excel 契約

與 FR-141、FR-142 同一份檔案往右延伸(決策者原則:每階段往右加欄,最後是完整軌跡)。「改善計畫」頁只列判不符合的評估目標,一列一個任務;同一條評估目標有幾個任務就佔幾列:

欄 內容 匯入
A(隱藏) part_id 比對鍵
B~J(灰,合併) FR-141 計畫欄:序號、控制項、實務要求、執行說明、評估目標、查核方法、受評人員、受評元件、稽核人員;D~J 群組預設收合 不讀
K~Q(灰,合併) FR-142 結果欄:稽核結果、佐證檔案、其他佐證、稽核發現、風險等級、風險說明、稽核建議 不讀
R(隱藏) task_id 比對鍵
S~T(淺藍) 任務、原指派人 不讀
U(黃) 執行人員:一格,多人以 ; 分隔;預設原指派人;必須是專案成員 讀
V(黃) 到期日:YYYY-MM-DD,日期驗證;必填 讀
W(黃) 改善措施;必填 讀

同一條評估目標的 A~Q 合併儲存格、垂直置中,評估目標之間粗上框;凍結窗格在 S 欄(往右捲仍看得到評估目標與任務名)。沒有「一格多值換行」,也沒有「往右長一組」:執行人員多人是唯一的格內多值,用分號。

「可選清單」頁只留「執行人員(專案成員)」。匯入預覽:異動列標黃、原值劃掉;執行人員對不到成員、日期格式不對 → 標紅「待確認」就地處理;同一任務出現在多條評估目標時執行人員與到期日須一致,不一致也標待確認;全部處理完才能確認。範例:prototype/sample/FR-143-改善計畫範例.xlsx。


§8

端到端流程

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
    participant PM
    participant FE as 改善計畫頁
    participant BE as BE/套件
    participant Job as 任務卡
    PM->>FE: 開頁
    FE->>BE: GET /poam/objectives
    BE-->>FE: 逐不符合評估目標:稽核缺失+底下的任務
    PM->>FE: 逐任務設執行人員、到期日、改善措施,儲存
    FE->>BE: PUT /poam/objective/<part_id>
    PM->>FE: 送出改善計畫
    FE->>BE: POST /poam/submit
    BE->>BE: 守門:有任務沒填齊 → 412 列原因
    BE->>BE: risk.status=remediating、poams.status=submitted、鎖定
    BE->>BE: 推進「內部缺失改善」站(close_round return_to_planning)
    BE->>Job: 每個任務退回第一站整條重跑、到期日寫回該任務、通知指派人
    BE-->>FE: 已送出
圖 4 — 內稽:排計畫 → 送出 → 退卡

外稽同前半段,送出後 close_round 走「母輪→pending_reverify」;launch_reverify 新任務從第一站開始、due_at 讀 task 到期日、指派人讀執行人員。


§9

拆卡草案

卡 做什麼 碰哪裡 依賴
1 套件:匯出補 timing/responsible-roles、剝 finding-id、POA&M 內嵌引用物件、task 狀態停用;all_items_closed→all_items_planned;earliest_milestone_dates 改評估目標層 pkg/jedi-oscal-v2/app/service/io/(1,720 行超標,新開 poam_export_parts.py)、pkg/jedi-compliance-audit/app/service/poam_app_service.py、audit_round_pass_transitions.py —
2 BE:poam_objective_app_service.py(讀逐評估目標含底下任務、整批存、送出守門+鎖定+寫回任務指派人與各站到期日+推進)、route、error code app/flow_control/service/、api/project/routes/、common/code/ 1
3 FE:新頁殼+src/components/grc/poam/;舊頁退役 FE 2
4 Excel:一列一任務 workbook 讀寫(合併儲存格、群組收合)、執行人員比對、預覽 poam_workbook_*.py、FE 預覽 1
5 退卡改為每個任務退回第一站整條重跑、到期日寫進每一站(D10/D12);覆核輪新任務同 not_met_job_redo_service.py、launch_reverify、新 job_restart_service.py 1
6 側邊選單「改善計畫」入口(D9):讀模型+端點、FE 清單頁、ui_routes 與權限 seed migration app/readmodel/(照 auditor_dashboard_service.py)、FE 新頁、scripts/sql/ 2

§10

不做清單

  • 任務完成追蹤、進度條、到期後自動結案(D2)。
  • 任務逐筆開新卡(FR-140 D1 已排除)。
  • 舊輪 POA&M 遷移或唯讀顯示(D8)。
  • 改善計畫報告 Word/PDF、概要頁籤(D7)。
  • 暫行緩解措施欄(D11)。
  • 一個任務多個里程碑、PM 自建改善任務(D3)。
  • poam_milestones.status/completed_at 刪欄(停用不刪)。

§11

坑與陷阱

# 坑 後果 對策
1 _close_on_pass 守門改成「計畫齊全」後,舊流程範本(只有 audit→poam→End)的 close_round 也走新守門 舊範本輪次若沒排任務會被擋 守門訊息列出哪幾條未排;舊輪已 closed 的不受影響
2 負責人對 party-uuid 查不到 匯出 responsible-roles 造假 uuid 不合規 查不到只寫 props 不寫 responsible-roles
3 related-findings 的 finding-id 被多處讀(_item_findings 等) 剝錯地方查詢壞 只在匯出 JSON 時剝,DB 不動
4 一張任務卡對多條不符合評估目標、各自期限不同 卡期限取哪個 D4:取最早;確認表先列
5 同一任務在 Excel 多列到期日或執行人員不一致 不知道信哪列 預覽標紅待確認,不猜
6 RoundPoamView.vue 890 行、poam_app_service.py 493 行、oscal_io_service.py 1,720 行 超標不准往裡加 全部新開檔,舊檔只改導向或退役
7 內嵌進 POA&M 檔的 finding/risk 與 AR 檔同 uuid 讀者以為兩份資料 官方允許(POA&M 可自帶 findings),匯出 remarks 標「引自稽核結果 」