本卡屬 FR-192(母卡 FR-192 母案(同清單上一張)),卡 M-4,批 4。只改 BE(主 repo,Repo 欄空著)。依賴:M-3、I-1。
主系統到 Agent 的回拉。設定通道加一類「這台 Agent 送出的回饋現況」(用 I-1 的查詢加對照表的已刪列),並把既有的「表一改就通知 Agent 來拉」機制加上回饋相關的四張表。🔴 只通知那一台(來源編號對到的 Agent),不是全租戶,否則任何人改任何回饋所有 Agent 都來拉。主系統端刪回饋時對照表要寫刪除時間,才知道要告訴 Agent「已不存在」。
extend:_agent_config_sections.py 加 feedbacks provider(用 jedi-issue list_by_source +對照表 deleted 列);_agent_config_notify._WATCHED 加 feedback_issues/issue_upload_files/issue_label_mapping → KIND_FEEDBACKS、labels → KIND_FEEDBACK_LABELS(只通知該 source_ref 那台,照 remote_agents name 的單台通知形狀);主系統端刪回饋時對照表寫 deleted_at(掛 jedi-issue delete 後,走 ORM after_delete 事件或 intake service 共用函式)
repo:~/Projects/Billows/Audit-Manager/compliance-manager-be
改既有:core/plugins/_agent_config_sections.py
改既有:core/plugins/_agent_config_notify.py 27(_WATCHED)
改既有:app/remote_agent/service/agent_feedback_intake_service.py(刪除路徑共用的 mark_deleted)
改既有:test/test_agent_feedback_intake.py
新開:core/plugins/_agent_feedback_state.py(provider 本體,照 `_agent_vulndb.py` 形狀)
core/plugins/_agent_feedback_state.py(照 _agent_vulndb.py):feedbacks_config_section(agent)——feedback_service.list_by_source(SOURCE_AGENT, agent.uid) 每筆對照表取 local_uid,組 [{local_uid, feedback_uid, title, description, type_label_uid, files:[{uid, name, size, where}], updated_at, deleted:false}];對照表 deleted_at 非空的列補 {local_uid, deleted:true};where:upload_files.storage_type==remote_agent 且 path==agent.base_url → agent,否則 cloud。version=內容 sha256。core/plugins/_agent_config_sections.py 註冊 KIND_FEEDBACKS → 上面那支。core/plugins/_agent_config_notify.py 第 27 行 _WATCHED 加 feedback_issues/issue_upload_files/issue_label_mapping → (KIND_FEEDBACKS,)、labels → (KIND_FEEDBACK_LABELS,)。🔴 feedback_issues 的通知要只送 source_ref 那一台:照 remote_agents 那列 name 的單台路徑(notify_agent_after_commit(agent_uid, [KIND_FEEDBACKS])),不要走全租戶;issue_upload_files/issue_label_mapping 沒有 source_ref,要先反查所屬 feedback_issues 的 source_ref,查不到(web 回饋)就不通知。labels 是全站,通知全部 Agent 可以。deleted_at:在 intake service 抽一支 mark_deleted(feedback_uid),掛 jedi-issue delete 之後(SQLAlchemy after_delete 事件監聽 FeedbackIssue model,或 jedi-issue 若有 delete hook 就用 hook;回寫寫清楚用哪種)。select * from compliance.agent_requests where kind='config_changed' order by id desc limit 1 只有那台;GET /agents/config?versions=feedbacks:x 回新內容。主系統改 Agent 來的回饋標題 → agent_requests 多一列 config_changed 只對那台 → Agent 拉 GET /agents/config?versions=feedbacks:舊 回新內容;改 web 來的回饋不通知任何 Agent;主系統刪該筆 → provider 回該 local_uid deleted=true;改 labels → 通知 feedback_labels;BE 重啟實打
~/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-192-2611-agent-console-feedback/design.md §3 決策定案、§5 詳細設計(本卡那節)、§6 拆卡表本卡那列、§8 風險;討論稿 discussion.md §4 只在想知道「為什麼這樣裁」時看~/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-192-2611-agent-console-feedback/prototype/index.html(純畫面,只取結構與資訊順序;文案依 i18n 重寫)guidant_agent/scan/app/local_runs.py(本機先存+同步欄位)、sync/app/outbox.py(待回傳佇列)、console/api/runs_routes.py(清單/404/resend)、files/app/blob_ops.py(附件存本機);主系統 api/source_scan/routes/agent_manual_scan_route.py(Agent 收單端點先例)、infra/upload_file/remote_agent_adapter.py(Agent 檔參照)、core/plugins/_agent_config_sections.py+_agent_config_notify.py(設定通道)、core/plugins/issue.py(jedi-issue 接線);jedi-issue app/feedback/service/feedback_service.py、api/routes/feedback_route.py、plugin/contract.py(SchemaExtensions);jedi-remote-agent app/service/local_run_service.py(ingest 形狀)、migrations/011-remote-agent-offline-operators.sql(RLS/GRANT 先例);FE src/views/feedback/system/SystemFeedbackForm.vue、console/views/Runs.vue、console/views/Logs.vue(Dialog)、src/views/source-scan/SourceFilePicker.vue(拖放)docs/system-design/system-integration/04-Agent到主系統API.md、05-主系統到Agent指令.md