control_objective_selections 從未寫入、terms-and-conditions 無表、AP 無任何匯出、FR-043 把六段塞進行程說明。assessment_findings.target_status_state 有 pending 113 筆,現行縮範圍只收 not-satisfied 會漏;P1 規則定為只排除 satisfied。method_keywords.py 已把「現場實地觀察」對到 EXAMINE,P3 做法列 B4 開工前問。17245d37d 登記、0769fc7d0 雛形一、54e76c319 討論稿、809644d90 雛形二、194a2f6eb 雛形三、8d28afc51 design;子卡 CM-2802~2809 一次建完。ffa1ff4b0、套件 f9d19cad、FE 6cd46ec6。首腦核三 repo commit、DEV AP 1162(四列 terms、單一 task、organization party、cm_app 權限)、守衛 118 passed、FR-040 17 passed;通過,待複測。repo.update() 略過 None 會吞掉「拿掉角色」,已修。PartyRepoImpl() 直接實例化,承襲 FR-040 先例。feature/FR-141),資料庫共用 DEV。pyproject.toml 整份還原,連 FR-140 三支套件的 path 設定一起刪了(venv 仍指本機原始碼,當下沒壞;下次 poetry 會悄悄退回發布版)。首腦補回那三行,未跑 poetry、未動 FR-140 的 BE。.venv、PORT=8001、四支套件 path 指套件 worktree;FE worktree node_modules symlink 主工作樹、API 指 8001。8001 起得來,A1 overview 路由回 401(未帶 token)=已註冊。.venv,必先 export VIRTUAL_ENV=$PWD/.venv;FE 的 package-lock.json 未入版控,worktree 沒有。1e0b69703、套件 ed48e82f(feature/FR-141)。套件不反向 import 主專案,由 DI 注入 A1 的 overview service;@transaction 巢狀沿用同一 session(查 jedi_common),set_tasks 與寫概要同一交易。亞航真 docx 實跑 parser→mapper 六欄正確。167 passed。通過、待複測。f6726c5b(worktree)。路由只換 component;日期以正則截到分(A4 帶秒自動吸收);唯讀時儲存/匯入按鈕整顆隱藏,並接能力點與授權唯讀;build 首腦實跑過。通過、待複測。ed55368c0、套件 9d54809a、FE eb05d5b8(feature/FR-141)。SSP 共用檔只搬移函式一字未改;首腦自取 9d54809a^ 舊版 _planning_by_control 與新 planning_by_control 在 DEV 全部 4 份 AP 比對控制項層輸出,差異 0(FR-140 AR 畫面不受影響)。通過、待複測。assessment_plan_app_service.set_tasks(:615-616 刪全部 activity,再經套件 set_tasks 刪重建全部 task)仍被 FR-043 docx 匯入 confirm 呼叫 → B1 合入後,匯入 docx 會清掉逐 AO 的 activity 與 task.associated_activities.subjects,無錯誤訊息。單卡各自驗收都過,是跨卡整合問題。首腦建議甲:docx 匯入不再呼叫 set_tasks。待決策者裁。B2 卡已先註記舊 /tasks 路徑。7a5f37a06、FE 4bd9e6b1(feature/FR-141)。匯出守門=參與者(同 A1 讀)。首腦以雛形亞航資料餵 ApDocxGenerator→LibreOffice pdf 逐頁看:標題帶稽核次、一~六段、三段「由…協助辦理。」+稽核人員、日期格式、橫式附件表合併格、方法「方法:指引」皆對。通過、待複測。2faa44d86、套件 6949a246、FE 53a4756d(feature/FR-141)。confirm 只剩 add_ap_party+put_overview;ensure_single_plan_task 就地更新、合併 associated_activities、不刪 activity → 整條 confirm 不再清逐 AO 資料。132 passed;runner 突變測試 3 紅。通過、待複測。party_type: organization 自 CM-1492 起就在,對應的是稽核單位而非個人,正確,非新問題。f45a622a0、套件 9b0e2290。pass_scope_rule 只排除明確 satisfied,AO 無判定時退回控制層判定(runner 發現:現行 AR 矩陣是控制層判定,不退回會整批帶入)。首腦自做突變(改回只收 not-satisfied)4 紅;169 passed。28f9c727、BE 4fa93a2c9。FR-140 AR 頁只改兩行註解。移除的五個函式 grep 無呼叫者;clone 用的是套件的 set_tasks(保留 uuid)。8001 舊 /tasks 回 404。182 passed、build 過。通過、待複測。.pyc 沒失效,B2 驗收時 4 條紅;清 pycache 後全綠,8001 保險起見重啟。已寫進 closing-and-handoff 首腦驗收側紀律。48718534a(條件含 key='檢視',不覆蓋管理員改過的)、詞庫 56b95932、i18n c02dbd96。DEV 已套。11995aee2,check 通過。整張轉待複測。6af14483):它在被 FR-141 刪掉的舊頁加過稽核次 Tag 與 passQuery。FR-141 A2 已沿用 useAuditPasses(同一個網址 query pass、唯讀橫幅、/ap?pass_uid),overview/objectives/export 都用那次 AP 的 apUid,功能沒漏。usePassTitle,與 FR-140 passLabel 同功能兩份、文案不同(「第 1 次 內部稽核」vs「第 1 次內部」)。補進 B3 卡順手收。5b311e072、FE ab171ca1(只在 FR-141)。沿用 ap_docx_parse_jobs(source_type varchar(20) 無 CHECK),無 migration。passTitle 重複已收。5b311e072^ 跑,同樣紅,證實舊債。ap_objectives_app_service.py:70-71(options.auditors)與 :85(put 驗證)取 AP metadata 全部 person 不看角色;A1 計畫概要只取 role=assessor。B5 加 assessed 後會混進稽核人員 → 本卡一併改成只取 assessor,共用 _role_of。1555d66ff、FE a39c8ac8(只在 FR-141)。角色判斷單一份 ap_party_roles;add_ap_party 延伸 reuse_names,預設路徑仍 409(只放寬受評與稽核同名)。186 passed。通過、待複測。subject_map = {**party_map, **ssp_map} 並加測試。教訓:開卡時寫「應該已涵蓋」的推測要標成待驗證,不能寫成結論。list_ap_parties 不分角色,docx 匯入比對稽核單位用全量名單。str.replace 找不到錨點,Python 不報錯,靜默沒寫進去(PartyRepoImpl、套件註解、mirror_parity、list_ap_parties、B4 改 FR-140 規則五項)。feature/FR-141 分支上那份——worktree 開出後 runner 只 commit 程式,首腦的文件都 commit 在主工作樹。合併時 FR-141 分支沒動過 FR-141 文件,git 保留 FR-139 新版,舊 STATE 不會合回來;worktree 移除後就不見。.venv/.../jedi_oscal_v2.pth 確認,改寫為「pyproject 不用動,但字面仍 pin 2.6.0,有人跑 poetry install 會被換回 Nexus 版」。audit_round_app_service.py 兩邊都動,合併後兩邊首腦各核一次。commits: 合併 BE 75d3af54d、FE c4b0a359、套件 e3be08aa;撞號修正 BE 11a2ff884、FE 9b1527f2(皆未 push) Notion: 十張實作子卡+雛形卡維持「修正待驗證」;母卡 CM-2799 加合併前現況、複測清單、收口事項 做了什麼:
feature/FR-141 三 repo 合回 feature/FR-139:先 dry-run(merge-tree),套件與 FE 乾淨、BE 只有 manifest.tsv 衝突(兩邊列都留,check 過)。77e9ee2c3)與 FR-141.B3 各自新增 GRC_412062,意思不同,git 自動合併不報衝突。合併前在臨時 worktree 把 FR-141 改 GRC_412063(BE 列舉+凍結表、FE 三語),再掃全 common/code 與套件確認合併結果無重複碼。audit_round_app_service.py:B4 的 clone_ap_for_next_pass/承襲 pass_no 與 FR-140.17 的跨稽核次退回都在;舊名 clone_ap_narrowed_to_not_met 無殘留;FE 無舊頁、usePassTitle、舊 /tasks 引用。flow_engine_route 能力點附錄,合併前 FR-139 HEAD 就紅,屬 FR-140.14);FE build 過。重啟 8000(worker 57461 沒動),FR-141 端點 401、舊 /tasks 404。path 綁定 PATH,迴圈變數取名 path 會讓 curl/ps 全部 command not found。 推翻了什麼: FR-140 首腦說「141 STATE 停在 10:48」——實為主工作樹那份是新的,過期的是 feature/FR-141 分支上那份(runner 只 commit 程式),合併時 git 保留新版。 留給下一棒: 決策者照母卡複測清單在 8000 測;主 pyproject 仍 pin oscal-v2 2.6.0,別跑 poetry install。commits(全在 feature/FR-139,未 push):FE 27 筆 10502f61…89dd55cc;BE 9 筆 d130ea370、986c97764、3af2c51fd、b4048bd5e、299a69b0d、a8aca0983、75a0c8a1e(另兩筆為他人 FR-142/FR-140 文件) Notion:CM-2803、2804、2807、2808、2814、2758 各補複測修正段,狀態維持「修正待驗證」 做了什麼(決策者複測清單第 1~3 項期間逐點修):
GET /ap/<uid>/report-title 取,其餘前端依 _sections 同規則組);評估目標唯讀為紀錄版(ApObjectiveRecord,決策者說這頁不動)。986c97764,決策者確認 Crowd strike 是單位後撤回)。b951379f 的摘要框、副標被否決)。 教訓:299a69b0d 少帶 return_response 的 status,決策者打開就 500。要用登入狀態實打。986c97764 先 commit 才看紅燈,結果是替身少 id)。commits(feature/FR-139,未 push):FE a927edd4(預覽)、75f72090(頁籤改名);BE 70be6a8cc(附件表稽核人員)、229a79b2e(Excel 頁名+舊檔相容) Notion:CM-2804、2807、2808 各補「測試棒第 2 棒修正」段,狀態維持「修正待驗證」 做了什麼:
useApExportDownload.fetchPdfUrl 少帶 meta.withHeaders。攔截器沒這旗標時直接回 body(Blob),程式卻 { data: blob } 解構得 undefined,new Blob([undefined]) 是九個字的假 PDF。STATE 列的假設②命中。objective_display_values 把 null(沿用)壓成 [],_objective 遇 null 改回退概要名單;存檔時 [] 本來就被寫成 null,沒有「刻意清空」第三態。add_token_to_db 登記,DEV login_tokens 多一列)實打 GET /ap/7cd12add…/export:docx 附件表 7/7 有值、PDF 回 %PDF-、「王阿財」8 次。既有測試 149 passed、FE build 過。畫面沒用瀏覽器看(本棒沒開瀏覽器工具)。 教訓:create_app(enable_socketio=False, enable_scheduler=False)+手動 register_blueprint(create_app() 預設不掛 REST blueprint,且預設會起排程與 8000 雙跑);token 要經 LoginTokenDomainService.add_token_to_db 登記,否則 jti 查不到一律當撤銷;腳本要 source .env,否則連到預設庫 compliance_manager。project_service 等檔並重啟 8000(19:34),只 add 自己的檔。 推翻了什麼:STATE §6 寫的測試專案 1547 已軟刪,現在是 1548。 留給下一棒:決策者畫面複測預覽與附件表;續測複測清單第 4~7 項。commits:BE 76420890e(稽核人員匯入可新增);FE d0edd306(下拉新增選項)、c43946da(預覽篩選固定全部)。「尚未開始」文案改動({label}{page}尚未建立)已隨 FR-140 的 785a6db4 一起進版。 Notion:CM-2807、CM-2808 補續段,維持「修正待驗證」 做了什麼:
__new:ensure_ap_auditor 同名非受評人員就沿用並設 assessor,否則 add_ap_party。confirm 先建拿 uuid → 重建 differ → put_overview → 再補一次角色 → put_objectives。785a6db4 正是如此)。 留給下一棒:決策者複測本棒四項+續測複測清單第 4~7 項。commits:FE 877de5d9(對不到的人預設新增+橫幅「將新增 N 位人員」);BE c1d0b33bf(Excel 整個控制項列) Notion:CM-2808 補兩段,維持「修正待驗證」 決策:Excel 控制項層走做法 A——匯入時展開,不存。被排除:B 存控制項層(套件資料結構+畫面「控制項預設」改存檔+報告稿都要動;OSCAL 一個 activity 對一條 AO,控制項層沒有落點)。先給決策者一份用真實資料改的範本看,看完才動手。 做了什麼:展開放在新模組 ap_workbook_control_rows.py,WorkbookDiff 建構時呼叫;被刪 AO 的補列用 keep_current 讓 _incoming_ao 沿用現值。 教訓:
\\n 會被轉成真換行,產出 SyntaxError;腳本內容改用 <<'EOF' 或寫完再修。 留給下一棒:決策者複測本棒全部項目+複測清單第 4~7 項。commits:BE 4af4f886e(diff.control_rows);FE 8683646f(ApControlRowPreview、總覽控制項列) 做了什麼:預覽時控制項畫面顯示 Excel 控制項列內容與套用數;總覽照 Excel 版面每控制項加一列控制項列,預覽時顯示控制項列內容、已變更 AO 列橘底。 教訓:Excel 加了「控制項層」後,畫面上三個看 AO 的地方(左樹、控制項畫面、總覽)都要一起想——只做匯入邏輯,決策者在預覽看不到差異會以為沒生效。
commits:BE revert b0140999e、b9645e8e1;FE revert 2f076ab5、拿掉控制項預設 ba0aa033 推翻了什麼:續 2、續 3 的 Excel 控制項列、預覽/總覽控制項列全部撤回(c1d0b33bf、4af4f886e、8683646f)。決策者裁示一併拿掉畫面「控制項預設」。 原因:決策者以為系統存了控制項層的設定(因為畫面有「控制項預設」可填),一路要求 Excel→預覽→總覽→Word 都要有控制項列;到 Word 時首腦說明「控制項層沒存」,決策者才發現誤會。 教訓:
push:BE 30b0f8363、FE ba0aa033、套件 3b94ad67(套件分支本機原無追蹤,遠端已有同名分支、可快轉,已 push -u)。BE 未 commit 的 pyproject.toml(FR-140 套件 path 設定)未推。 Notion:母卡 CM-2799 補收口五段+待辦後轉 Done;子卡 CM-2800、2802~2810、2814 共 11 張轉 Done。 決策:決策者裁示「當我都驗過」、收卡;問進版時改裁只 push、不發套件、不進版。理由:四支套件 FR-140 也在用,發版要等 FR-140 收口;套件不發,主專案 pin 還指 Nexus 舊版,進版等於出一個 poetry install 就壞的版本。 留給收口那棒:STATE §3 清單,第 1 項(套件發版)是其他項的前提。
commits:115c8e3e1 design.md v2(「實作後改判」節) Notion:開 CM-2835(SPEC 頁、使用手冊、README、需求站 HTML),母卡追加連結。 決策:決策者裁「派給下一棒」。design.md 首腦自己改(今天定案的規則首腦最清楚);其餘量大的交新 session。design.md 原文定位是「設計決策不回頭改寫」,所以改判集中寫成一節、內文舊規則加刪除線指過去,不改寫原決策。
commits:runner 54a600127(SPEC 頁、使用手冊 audit-plan-guide.md、README、需求站 HTML) Notion:CM-2835 首腦復核通過 → Done。 核對:SPEC 無舊頁與控制項預設殘留、規則與今晚定案一致、與 FR-140.C1 同頁合併無衝突;「Excel 三欄留白會清掉」首腦實跑匯入比對確認;mkdocs --strict 重跑過。打折:畫面未照手冊實走,列手測。