本卡屬 FR-166(母卡 CM-母卡號(建完補)),卡 P2-1,階段 P2 離線能做事、批 3。只改 evidence-agent。依賴:P0-4、P1-3。
Agent 執行任務的那條路,把「回報給誰」抽成可以換的介面,主系統派的走雲端、手動的走本機;順便讓 ZAP 的網址也過清冊。
核心執行路徑重構,兩條路徑共用一支;清冊規則擴充要守衛
extend(抽共用):_run_one 的 ack/result/report-sink 抽成可注入介面,雲端 sink=現況、本機 sink 新增;不複製 _run_one;allowed_targets.py 加網址欄位解析(改既有 _target_networks)
repo:~/Projects/Billows/Audit-Manager/evidence-agent
改既有:core/task_executor.py 369(淨減)
改既有:core/allowed_targets.py 203
新開:core/task_sinks.py
新開:core/local_runs.py
細節在 design.md 對應段(~/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-166-2610-agent-standalone-console/design.md §5,開 design.html 看導覽),本段只列本卡要做到的點:
core/task_sinks.py:TaskSink protocol(ack/result/report);CloudSink 把 _run_one 現有三段逐字搬;LocalSink 寫 local_runs、report 走 file_upload_service。_run_one(task, sink);既有呼叫改傳 CloudSink();diff 要是淨減。start() 擋。allowed_targets.py:_URL_FIELDS 加 ZAP 網址欄位;urlsplit().hostname → getaddrinfo → 每 IP 過 _is_allowed_ip;解不到=拒。主系統派工行為不變(既有 tests 綠);本機 sink 寫 local_runs;第 3 個掃描排隊;ZAP https://x/ 解成清冊外 IP 被拒、清冊內放行;離線 30 天/未同步時 start() 拒
對照雛形:~/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-166-2610-agent-standalone-console/prototype/index.html(上方「跟著走」)。