只追加、不改寫既有 block。 每棒一個 block:commits/決策/教訓/推翻了什麼。 現況看同目錄
FR-067-STATE.md。
卡:子需求 CM-1351|T-1.1 CM-1357|T-1.2 CM-1358 commits:9f83973b feat(FR-067.1): Agent 清單補能力與在線狀態+修好自動挑機 改動:13 檔(BE code 8+test 4+spec 1),未動 DB、未碰 STG/POC
D-1.a 新增 get_dispatchable_agents(),而非改掉既有 get_agents_with_capability() 派工要濾離線、清單不能濾離線——同一支方法答不了兩個問題。若直接把在線條件加進既有 方法,清單頁會把離線機藏起來,使用者找不到機器又看不出原因(正是 memory feedback_verify_data_source_before_hiding_empty_display 講的失敗模式)。故拆兩支、 docstring 互相交代分工。既有方法保留原語意,零回歸。
D-1.b 修在 domain service,不在兩個 caller 各修一次 盤點發現 _pick_agent 與 test_connection 早已共用 get_agents_with_capability (FR-056.5 就抽好了)。卡片文字看起來像要改兩處,實際只需換掉共用的那一支,兩邊 自動對齊——這正是 D9③「測通的就是會執行的」最省的達成方式。沒有另寫第二套挑機邏輯。
D-1.c 排序鍵選 id uid 是隨機 UUID、name 使用者可改,兩者都不穩定;id 單調不變。穩定性有反向 斷言守(輸入順序反轉,輸出不變)。
D-1.d is_online/utc_now 搬到 common/util/agent_auth/heartbeat.py domain 層要做在線判定,但原本這兩支住在 app 層,domain 不得反向依賴 app(DDD 層級 規範)。搬到 common 並在原處 re-export,既有 import(含 3 支測試檔)零改動。
D-1.e 在線欄位命名 is_online(清單)vs online(管理頁)並存 管理頁 RemoteAgentDetailResponse.online 是 FE RemoteAgentManage.vue 已在用的既有 契約,動它要連 FE 一起改且不屬本卡範圍;新欄位依 design.md §5.6 契約命名 is_online。 兩者語意與門檻相同,已在 serializer docstring 交代,避免後人以為是不一致。
① 「兩處各寫一套」的卡,先查是不是早就共用了 卡片描述兩個檔案座標,容易直覺開兩處修。實際 grep 後發現 FR-056.5 已收斂到 domain service,只需換一支。先 grep 行為再動手省掉一次重複造輪子(CLAUDE.md「新增 method 前先找既有能力」鐵則的正面案例)。
② 環境設定值可能與設計文件舉例不同,別把文件數字寫死 design.md 通篇寫「900s=300×3」,但 DEV .env 的 AGENT_HEARTBEAT_INTERVAL_SEC=60 → 實際門檻 180s。卡片要求「沿用既有常數不自創」正是為此。驗收時若拿 900 去對會誤判。
③ 同目錄可能有平行 session,commit 前必須逐檔認領 本棒 commit 前 git status 出現 27 個我沒動過的檔(FR-067.2 的 group/assignment 表)。 用 ls -lT 比對修改時間發現是當下正在寫入的平行 session 產物。若當時用了 git add -A,會把對方未完成的半成品掃進我的 commit。判定方法:比對檔案 mtime 與自己的作業時間窗、隔一段時間再看 git status 行數是否還在變。已寫進 STATE 警示。
④ 改了共用 canonical,要順手改掉 mock 它的測試——否則測試綠得沒有意義 四支測試檔 mock 的是舊方法名。不改的話 MagicMock 會對新方法名回傳 Mock 物件, 測試可能仍「綠」但驗的是空氣(其中 test_no_available_agent_raises_bad_request 原本就會因此變成假通過)。
與第一棒(.1 地基)平行進行,非接續。兩棒各自 append 自己的 block。
commits(BE,皆未 push):9bcd02f5(T-2.1 migration)/69e6906d(T-2.2 DDD 四層+彙總函式,28 檔) Notion: CM-1359/CM-1360 皆回寫「修正待驗證」+白話已完成修正段+commit hash;子需求卡 CM-1352 維持 In progress 待驗收。
scripts/sql/2026-08-23-fr067-2-detection-multi-agent-tables.sql——兩張新表 +detection_executions 擴 group_uid/assignment_uid+補三支索引(缺口 11 還債)。 只套 DEV,schema_migrations+manifest.tsv 皆已登記,不做 backfill(D8)。detection_executions 側同步擴欄並加 list_by_group/list_latest_per_assignment;彙總計算獨立成模組級函式。BEGIN…ROLLBACK)驗 CRUD/DISTINCT ON/唯一約束/軟刪加回/列鎖,無殘留; ddd-compliance-reviewer 掃過 0 findings。detection_group_status.py)而非 group domain service 私有方法。理由:收口、單組重跑、取消、列表呈現四個入口都要算同一件事,私有方法會誘使 各入口複製一份成第二套真相。group domain service 保留 compute_status() 薄轉呼叫當 domain 入口,不重寫邏輯。reopen() 另立一支而不走 update(entity):repo.update() 是「value is not None 才寫」語意,closed_at=None 會被靜默 skip,舊收口時間清不掉——這是幽靈覆寫防護的反面 代價。故 repo 內另開 reopen() 直接操作 model 欄位。被排除:entity 加 clear_closed_at 布林旗標(把 repo 寫入語意漏進 entity,更難懂)。WHERE is_delete = FALSE):table-level UNIQUE 會讓軟刪列繼續佔 slot,「移除某台再加回同一台」會撞 UniqueViolation。這個坑 uq_jedt_job_active 當年踩過,其 migration 註解留有前例記載,直接沿用。2026-07-26-fr056-2-jedt-fix-rls-delimiter.sql(修正後: slash-delimiter + is_super_admin = 't'),不是 job_execution_detection_tools 原始建表 migration(逗號 delimiter + 'true',該版是壞的,當年 FE 手測才炸出來)。 新表照抄原始版就會複製同一個 bug。compute_group_status 把任何非 succeeded/failed/cancelled 的值都當未終態(回 running),而不是丟進 partial_failed。理由:保守——寧可不收口讓 人工看,也不要誤判成 succeeded 而觸發 D5 auto 自動完成任務。TenantScopedMixinModel 讓「獨立 script import model 做 DB smoke」行不通:該 mixin 只在 ENABLE_MULTI_TENANT=true 時才產出 tenant_id/org_unit_id,且帶 ForeignKey("tenants.id")——FK 目標表要整個 model registry 載入才解析得到,否則炸 NoReferencedTableError。資料層實跑驗證改用原生 SQL 打 DEV(包在 BEGIN…ROLLBACK 內) 反而更快更乾淨,且驗的正是與 repo 相同的 SQL 形狀(DISTINCT ON 那段是直接把 repo 產出的 SQL 抄過去跑)。75a0a3f5),本棒是用 cat > 整檔覆寫——working tree 內對方版本 被蓋掉。發現後以 git checkout <commit> -- <path> 復原對方版本,再把自己的內容以 Edit 併入(STATE 併節、LOG append block)。教訓:交接雙檔在平行作業下要當共享檔對待, 一律先 git log --oneline -- <path> 看有無新 commit,再用 Edit 併入,不要 cat > 整檔寫。無。D1–D9 皆照 design.md 實作,無偏離。
start_execution 展開、收口、重跑、取消):那是 .4 範圍, 本棒只交付資料層能力。detection_orchestration_service.py 一行未改。agent_assignments 欄位屬 .3。detection_executions 的 group_uid 全為 NULL=legacy 筆,讀取端視為單筆獨立顯示。與 .3(綁定設置)平行進行。本棒範圍限
detection_orchestration_service.py/remote_agent_domain_service.py/ detection_tools route+DI+error code /task_execution_query.py,未碰job_service.py的 binding 寫入與 FE。
commit(BE,未 push):e6283532(11 檔:BE code 7+test 4) Notion:CM-1363/CM-1364/CM-1365 皆回寫「修正待驗證」+白話段+commit hash; 子需求卡 CM-1354 同步「修正待驗證」。 DB:無異動(表在 .2 就建好)。
start_execution 展開成 group+N 筆 execution+N 張工單;D3 逐台驗證 收集全部不合格一次 400;無 assignment 走 fallback 隱含單組(仍建 group); running group 守門與自動派工冪等上移。_close_group_if_terminal() 列鎖收口——彙總落地/auto gate(只認 succeeded)/通知 hook 點;complete_job 冪等防護;409 地雷解除。diagnose_dispatchability() 而非複用 get_dispatchable_agents(): 後者只答「有哪些可派」,答不出「這台為什麼不可派」。D3 要求逐台列原因(避免使用者 修一台再撞下一台),故條件逐項檢查而非一次過濾掉。被排除:用集合差集推斷原因 ——推不出「同時 disabled 又 offline」這種多重原因,訊息會失真。代價是兩支的資格 條件要同步維護,已在雙方 docstring 互相交代。assignment_uid=NULL 自成一條分組線(.2 已實跑確認 PG 的 DISTINCT ON 對 NULL 的語意正是要的),收口只有一套。_notify_scan_result 的九項內容測試(TestScanNotificationContent 共 7 例)要一起改造。現階段仍是單筆各發一封(行為與 .4 前相同),收口只寫 log。_auto_dispatch_detection_scans 冪等條件「加」而非「換」:卡片寫「改『該任務無 任何 group』」,但直接換掉會讓 D8 不 backfill 的舊資料(有 execution、無 group)被 判成「沒派過」而重派一輪。改成兩條並存(無 execution 且 無 group)。這是對 卡片指令的偏離,理由是照做會製造重複派工。start_execution 從 {agent_task_uid, execution_uid} 改成群組形狀。grep JobExecutionDrawer.vue 確認 FE 只看呼叫成功與否、不讀 body,故無破壞。沒 grep 就改的話,破壞會等到 .5 串 FE 才浮現,屆時查起來像是 .5 自己弄壞的。replace 沒命中),出現「看起來沒轉紅」的假象——改用檔案比對 確認替換真的發生後才看到正確結果。突變測試本身也要驗突變真的注入了。_auto_dispatch_detection_scans 冪等條件改『該任務無任何 group』」 ——改成「加一條」而非「換掉」(理由見上方決策段)。這是本棒唯一對派工單指令的偏離。receive_result 不吞例外的既有行為(卡片明示不必改)。_notify_scan_result 仍每筆一封)——T-5.2 範圍,收口路徑 ③ 已留 hook 點。job_service.py binding 寫入(.3 平行 session 的範圍)。error-code.json(5 個新碼)——.4 範圍不含 FE,已寫進 STATE 下一步。與第四棒(.4 執行展開與收口)平行進行。接手時 .4 已收工並 commit(
e6283532/10d6b43b), 故本棒的交接雙檔改動是併入 .4 的版本(Edit 就地併節,未整檔覆寫)。
commits(皆未 push):BE f6e27786(11 檔)/FE 996ed22(3 檔)。DB 無異動(表是 .2 建好的)。 Notion:CM-1361/CM-1362 皆回寫「修正待驗證」+白話已完成修正段+commit hash+執行紀錄; 子需求卡 CM-1353 維持 In progress 待驗收。
DetectionToolBindingSchema 擴 agent_assignments;寫入端 diff-sync(增/改/軟刪) 掛在 _replace_detection_tool_binding 的 update 與 create 兩分支;讀取端每列 enrich agent_name/agent_online(app service 層批次查,不在 infra JOIN);新增兩個 error code。ProjectPlanningView 檢測工具區新增「Agent 分派」列表(agent 下拉+掃描目標輸入+ 增刪列),空列表顯示「自動分派」說明;離線 agent 標示且不可選;已被別列選走的一併反灰; i18n 中英雙語補齊。沿用既有 tokens 與全域 class(hint-bar/form-label),未新增自訂樣式。npm run build:DEV 通過;ddd-compliance-reviewer 0 findings。 依測試政策未寫新單元測試(卡上未要求)。agent_assignments 的 None vs [] 分開語意:None=不動既有、[]=清空。理由:規劃頁 有「只改任務名稱」的 PUT 路徑,若把未帶欄位當清空,改個名字就會把分派設定洗掉。這與同一 schema 內 tool_params/completion_mode 的 None-skip 慣例一致。被排除:一律當清空 (簡單但會誤刪)、一律當不動(則永遠無法清空回 fallback)。agent_uid 當第二鍵(原本只用 uid):見下方教訓①。被排除:要求 FE 必須 帶 uid——契約上做得到,但「前端漏帶就 500」是脆弱設計,且 agent_uid 本來就是 DB 唯一約束的 欄位,用它配對才與唯一性語意同源。agent_assignments(含空陣列):因為空陣列是有意義的值(清空),省略才是 「不動」。若 FE 用「有值才送」的常見寫法,使用者永遠刪不掉最後一組。uq_jedta_binding_agent_active。這正是「批次驗證」紀律的價值:九個 情境一次跑完,兩個坑在同一輪暴露,修完再驗一輪就收斂;逐項驗會變成兩輪。add/update 都立即 flush,故 diff-sync 的操作順序有語意:「先增後刪」在 「把 A 台換成 B 台」時會撞約束(A 還沒讓位)。軟刪必須排在新增之前。這類「同一交易內 多筆寫入互相踩」的坑,光看 code 想不出來,是靠情境 4(整台換掉)跑出來的。get_job/list_jobs 走 GrcJobRepoImpl._batch_fetch_job_tools,但規劃頁任務面板 prefill 實際走 control-tree 的 raw SQL(ssp_control_implementation_service + ssp_control_implementation_query)。 只補前者的話,存檔當下畫面正常、重新整理設定就消失——使用者會回報「存不進去」,實際 DB 有資料。任何加在綁定上的新欄位都要同時補這條。發現方式是實作 FE 時追 mapAoJobs 的資料來源,不是靠 grep 猜。無。D2/D8 皆照 design.md 實作;卡片指定的檔案座標與 §5.6 契約皆未偏離。
detection_orchestration_service.py/detection_result_handler.py(.4 平行 session 範圍, 一行未改)。error-code.json(GRC_400107/GRC_400108)——與 .4 的 5 個一併留給 .5 串 FE 時補。commit(未 push):0dc088d9(44 檔,含 2 支新測試檔)。DB 有異動:只套 DEV (2026-08-24-fr067-7-per-assignment-scheduling.sql,已入 schema_migrations + manifest.tsv)。 Notion:CM-1366/CM-1367/CM-1373 皆回寫「修正待驗證」;子需求卡 CM-1355/CM-1372 維持待驗收。
三張卡合一個 commit:orchestration service 同時承載執行紀錄列表、收口通知與展開/取消鏈, 拆開 commit 會留下中間跑不起來的狀態。
list_executions 改回兩層形狀(group → executions),每筆補 agent_uid/ agent_name/assignment_uid/scan_targets/is_latest;legacy 筆與「群組列查無」 一律走「單筆自成一組」合成分支(is_legacy: true)。順修兩處既有 N+1(缺口 11): scan_params 與 report_file_uid 各補批次版,剝除邏輯抽成 module-level 純函式共用。_notify_group_result(整組一封,每 assignment 一列: agent/目標/狀態/發現數/時間/失敗原因),三通道同步;單筆通知只留給 legacy 無 group 的筆。_dispatch_notification 的 error_message 參數改成 failed_tone 布林。agent_tasks 的 scheduled_at、 detection_executions.status 的 scheduled 語意)+領單部分索引;領單查詢加時間過濾; 綁定 API 讀寫帶 scheduled_at;展開時快照進工單與 execution 狀態;取消排程組短路; 「立即開始」端點;ack 時 scheduled→running。common/util/scheduled_time.py(naive 視為 UTC):scheduled_at 落 TIMESTAMPTZ,但 jedi-common 的 db_mw.DATETIME_FIELDS 只涵蓋 created_at/updated_at,本欄 不會被自動轉時區。FE 若送不帶 offset 的本地時間,psycopg 會以 session TZ(三環境皆 Etc/UTC)解讀 → 設的凌晨兩點變成早上十點才開掃,且畫面完全正常(存什麼讀什麼)。 被排除:靠 DB session TZ(隱式、換環境就漂)、在 BE 轉成台北時間(跨時區使用者看到錯的 牆鐘時間)。list_dispatchable_for_agent,不改 list_for_agent_by_status:後者是 FR-058.7(D25)下載授權判定用的,要看 pending/dispatched/running 三態,不該被排程時間 過濾(已領走的單本來就過了時間,套上去 agent 取檔會被自己人擋掉)。兩支分家有測試守著。 被排除:在既有那支加參數——共用一支就得在每個 caller 判斷要不要過濾,是漏判的溫床。compute_group_status 視 scheduled 為未終態)。列表的「2 組:1 執行中、1 排程於…」文案 由 FE 依明細組成。被排除:group 加第五個狀態——會讓 D4 彙總表從四態變五態,而收口判定 只關心「終態了沒」,多一態是純負擔。fail、Nmap 系 findings),取不到時填 0 會被讀成「掃了但什麼都沒發現」,與「這個工具不回報這個數字」是 完全不同的意思。list of tuple 設計的理由)。_is_unclaimed_scheduled 用直接取屬性會炸既有測試(實跑抓到):測試 fixture 是薄的 SimpleNamespace,沒有 status 欄位。改 getattr(..., None) 時順手想清楚了保守方向該往 哪倒——判不出來就走「打 agent 取消」(多打一次頂多拿到「查無此任務」),而不是短路 (該打沒打=掃描還在跑卻標成已取消)。容錯的預設值本身是設計決策,不是隨手填。Mon, 24 Aug 2026 18:00:00 GMT vs grc job 路徑的 ISO 2026-08-24T18:00:00+00:00——同一個欄位兩種格式,FE 得寫兩套解析。 這條路徑不經 marshmallow schema(本檔 reviewed_at 早有 .isoformat() 的既有慣例,只是 沒人在加新欄位時想到要跟)。加欄位到 control-tree 時,格式一致性要跟資料存在性一起驗。is_latest 與批次化的斷言都有牙齒,但「多筆 legacy 各自成組」 一開始沒鎖住——把分組鍵從 f"legacy:{e.uid}" 改成常數 "legacy"(=所有舊筆擠成一組) 測試照樣全綠。補了一條測試才抓住。「跑綠了」不等於「守住了」,突變測試是唯一的檢驗方式。{"name": "排程測試任務"},把一個真任務改名了。從 api_logs.response 撈回原名 (GCB Scan use upload profile)並走 API 還原(不是 raw UPDATE——名稱會同步回寫 BPMN 模板 XML,直接改表會讓兩邊不一致)。教訓是驗證用的寫入要挑自己建的資料,或先記下原值。無。D6/D10 皆照 design.md §5.6/§5.7/§5.9 實作;T-4.2 留的收口 hook 點 ③ 依約接上。
error-code.json——本棒新增 DETECTION_TOOLS_409015,連同 .3/.4 遺留的六個 共七個,一併列在 STATE 的 FE 待辦契約節。manifest.tsv 有兩支既有未登記檔(2026-08-18-cm1283-*/2026-08-20-cm1317-*,非本棒 產生,commit 早於本棒)——check_migration_manifest.sh 因此仍 FAIL,本棒新增的那支已登記。交付:JobExecutionDrawer 群組卡片 + 排程 UX 三端 + 十支 error code i18n。 FE repo feature/FR-067:cb458a6(群組卡片,CM-1368)/055d9c2(設定端排程 chip, CM-1374)/80e1c29(error code + App.vue 明細併陳)。未 push。BE repo 無程式異動 (僅本 STATE/LOG)。
T-7.2 的執行紀錄那一端(排程中徽章/立即開始/確認框)落在 cb458a6 裡——與 T-5.3 同一個 檔案同一段模板,硬拆成兩支 commit 反而讓任一支單獨看不成立。
executions 從 ref 改成 computed(攤平 executionGroups),而不是把既有以「單筆」為 單位的邏輯全部改寫。sticky 源碼檔追溯、執行中判定這些都只關心「有哪些筆」,不關心分組; 留一個攤平視圖讓它們原封不動,改動面從整個檔縮到只有渲染層。group.status:BE 視 scheduled 為未終態,群組層在排程等待期間 仍是 running。但使用者的心智是「機器正在掃」vs「時間還沒到」,兩者同一個顏色會讓人 以為卡住。故 groupStatusKind() 在 group 為 running 時往下看明細:全 scheduled → 中性 「排程中」,混合(有一台真的在跑)→ 仍算「執行中」(已經有機器在動了),彙總列補講 「1 執行中、1 排程於 8/25 02:00」。groupRenderRows() 合成單一清單,只差 history 旗標) ——兩者內容完全相同,只是暗一階且無動作鈕。分成兩個 v-for 會變成同一段七十行模板維護兩份。ACTIVE_EXEC_STATUSES = ['running','scheduled'] 在 FE 也集中成一個常數,對齊 BE 的 _ACTIVE_EXECUTION_STATUSES。前一棒 LOG 已警告「別在各處另寫 == 'running' 字面值」, FE 同樣適用——漏掉 scheduled 會讓排程中的組取消鈕不出現。scheduled_at 一律送出(含 null):它是「每次依送來的值覆寫」語意,與整包 agent_assignments 的「未帶欄位=不動」是兩個層級。移除 chip 要真的清掉排程。is_latest 缺陷——這是靠「跑一次真的 API」才看見的。 單看契約文件與模擬 payload,is_latest 的語意完全合理;但 DEV 既有 10 筆 legacy 跑下去, 9 筆變成「歷史」而在預設收合下消失。分組鍵 (group_uid, assignment_uid) 對 legacy 筆 全是 (NULL, NULL),卻又讓每筆各自成組——兩個決策各自合理,湊在一起就矛盾。 作法上的收穫:把 FE 的實際 helper 函式抽出來(esbuild 去型別)餵真實 API 回應跑, 比讀程式碼想像有效得多,成本也只有幾分鐘。DETECTION_TOOLS_400017 的 BE msg 尾端帶逐台原因, 而 t(code, {default: msg}) 有翻譯時整個蓋掉 default。交接文件已標「需保留 msg 內容」 卻沒說怎麼保留——照字面補翻譯就會把明細吞掉,只剩一句空泛的「有 Agent 無法派工」。 「補上翻譯」不是無害動作:對「訊息本身帶動態明細」的碼,補翻譯等於降低資訊量。DETECTION_EXECUTION_404002 是四顆新按鈕都會撞到的碼卻不在清單上。清單是前一棒的 記憶產物,端點實打才是真相——花兩分鐘打一輪 404 就補到了兩支。failed。照 200 報「已取消」是謊——那幾台的掃描還在對方機器上跑,只是本地紀錄被 標成失敗。凡是 best-effort 端點,FE 都要讀回應內容而不是只看 HTTP 狀態碼。無。§5.9.4 UX 三端與 STATE「FE 待辦契約」皆照做。唯一與交接文件不符處是那節寫「七個 error code」(實為八支,另補兩支漏列),已在 STATE 就地更正。
b205e07a,同棒稍後,user 指示)FE 發現的缺陷改在源頭修掉,不只靠 FE 保底。修法上的重點是「不要選一支鍵去改」—— _group_executions()(分卡)與 _latest_execution_uids()(判最新)本來就是同一個分組概念 的兩面,兩處各寫一份鍵才是病根;抽成 _execution_card_key() 共用,並在兩支 docstring 互相標註「必須同鍵」的義務,才是讓它不再漂移的作法。真群組行為零變化,僅 legacy 路徑受影響。
回歸測試斷言刻意寫成性質(「每張卡至少有一列 is_latest」)而非特定 uid 的期望值—— 分卡規則日後再變,這條仍然守得住。依 [[feedback_mutation_test_proves_assertion_has_teeth]] 做了突變測試:鍵改回舊版該測試立刻紅、還原後綠。
修後重啟 BE、以 DEV 真實資料重打 API 確認 10 張卡各有 1 列當前(修前 1 有 9 無),並回頭用 FE 實際 helper 跑修好的 payload,確認 FE 保底不會因此重複計算(10 列渲染 10 列、無重複)。
test_every_card_has_at_least_one_current_row,屬核心共用邏輯的回歸,符合政策條件②)。本棒角色:協調者——逐棒驗收 .1–.5+.7 全部六棒(全數通過)、陪跑端到端驗收、 拍板三個驗收回饋修項的修法。無程式 commit(僅本 STATE/LOG)。
/etc/guidant-agent/agent.env、程式 /opt/guidant-agent/versions/0.2.28(current symlink)。已註冊成功: remote_agents id=17 ubuntu-lab-03、https://192.168.50.123:8443、 [file_storage, detection_scan]、在線。user 正在跑單台端到端場景 (基本掃描/排程/立即開始/取消/失敗重跑)。enroll token 頁回的 endpoint 是 AGENT_CLOUD_ENDPOINT 原值 http://10.8.0.6:8000/api/1.0(10.8.0.6=user Mac 的 VPN IP,BE 跑本機),agent 端會 自己再補 /api/1.0 → 打成 /api/1.0/api/1.0/agents/register 404。當場修法=agent.env 的 CLOUD_ENDPOINT 拿掉路徑後重啟即註冊成功;根治留給修項 2。
target_url)/SonarQube(只讀 repo_url)無效,UI 卻照樣渲染目標欄。 修法:按 param_schema 是否含 hosts 切——hosts 型(openvas/openscap/inspec/gcb/nmap) 照現狀,單一目標型分派列只剩 agent 下拉(用 param_schema 判斷,不寫死工具清單); BE 展開時對非 hosts 型忽略 scan_targets 防禦。agent_enroll_token_service.py:62 直接回含 /api/1.0 的原值,使用者照抄必 404。修法二擇一(下一棒定):BE 顯示時剝路徑, 或 agent 端 enroll 正規化容忍帶路徑。is_latest 語意:legacy 筆(assignment_uid 全 null)被算成同一條 latest 線,10 筆只有 1 筆 true(FE 保底已擋住消失問題)。該修成 legacy 每筆自成一組 各自 true。影響低(D8 資料會重置)。ZAP 項卡已開(卡號見 Notion FR-067 母案 CM-1350 下最新子卡);後兩項可併一張 「驗收回饋修正」卡或掛進 .6。
systemctl list-units 確認形態,別假設 compose。假設錯形態會去找不存在的容器與 compose 檔,全程撲空。is_latest 語意問題——「單元測試綠」不等於 「真資料形狀對」。真實存量資料(legacy NULL 欄位)是契約文件照不到的角落。無。前六棒交付與決策皆維持;b205e07a 修的卡片分組鍵與修項 3 的 is_latest 語意是 同一區塊的兩個獨立問題(前者已修、後者待開卡),不是推翻。
本棒角色:協調者——收 user 端到端驗收回饋、開六張卡、派四棒 runner(皆開 case 給新 session)、逐棒抽查、user 驗後收 Done。本體 commit 僅 STATE/LOG。
9809d29 +BE c408814f)②掃描目標單一入口+Agent 分派上移(8633ed6)③預設備妥一組 (fe10773)④profile 純下拉(BE 5ec85bee)⑤重跑歷史收合 v-show 被 PrimeFlex !important 壓過(3a9a213)+排程小日曆 minDate(d10ab5a)。第⑤波實際收合行為 留待多列場景複驗。06e98031/FE 4081e58)—— agents[0] 固定取首台在多 agent 下與實際執行脫鉤。_exec_with_cancel 原「排空即丟」)+Rocky 檔名 推 rl(evidence-agent 6fdd541,bump 0.2.29 ae9f4c9)。runner 順抓上層彙整 「從頭截 300 字」會切掉尾端原因的連帶坑。0.2.29 尚未部署到兩台 agent。8c24e212/FE 83248dc +migration 拿 uq_jedta_binding_agent_active,DEV+188 stack 已套)。docker stop(unless-stopped,不自啟);在線 agent=id=9(60.166)+id=11(50.123)。profile:<uid> → _profile 凍結快照)原在合併前,分派列覆寫後第二列會拿 A 基準檔跑 B 設定且被自家下載授權閘擋,靜默掃錯基準不報錯。runner 查證後改為 「先合併再展開」並加不變量測試。協調者拍板的「零改動」假設也要 runner 驗——寫卡時 該標「假設,實作前查證」。rl 不是 os-release 的 rocky。一輪驗收四台目標三種情況。user 提出:Linux 共用帳號模式在 Windows 只對「有 AD」環境成立;無域(workgroup) 機器同名帳號互不相干、逐台建帳+密碼同步不可維運,且有 UAC token filter 限制。 協調者分析與三層建議(短期手冊+前置腳本/中期 per-分派列憑證組覆寫復用 1379 地基/ 長期 PAM)已寫進 STATE 待辦第 5 項,下個 session 首先討論。此為分析記錄非定案。
本棒角色:協調者——收續輪回饋開卡派工抽查、主導 FR-067.8 設計拍板與三棒落地、 FR-068 設計定案、環境救火(ZAP)。本體 commit 僅 docs(含一次誤掃事故,見教訓)。
5ca869e7 內+FE 整份 param_schema da33373+SonarQube upload per 列 fda3921b/ a4c5ab4)全完成抽查通過。文件二輪同步 CM-1393(a4f063bb)。feedback_fr067_push_delegated_after_review。5ca869e7):顯式 add 自己的檔 擋不住「別人已 stage 的一起進 commit」——同目錄有 runner 時,commit 前必看 git status 的 staged 區,有別人的東西就停。歸屬靠 Notion 卡標注收拾,不 rebase (force push 會弄壞部署 runner 的 checkout)。-x proxy 姿勢打,直接 GET 永遠 refused。571b5b9e(1395 的 BE 半)未抽查未 push。本棒角色:協調者——收 1395/96/97 抽查 push、驗收 11 卡收 Done、主導 v1.16.0 進版全鏈(定版→出包→189 全新安裝)、.6 收尾棒派工、安裝包 P0 事故止血與開卡。