§1
2026-10-29 首腦:討論 → 討論稿 v1~v3 → design v1 → 開卡
- 決策者提問起點:「檔案下載後有人來我的電腦就可以直接開檔」;工研院要裝解密軟體太麻煩。
- 裁示序列:先不做撤銷(IRM/DRM 整條排除)→ 不要使用者自訂密碼(定案系統產、畫面顯示一次)→ Agent 離線寄不了信要搬通知模組?(確認密碼只走畫面不寄信,不搬)→ 加密函式放哪?(定案獨立套件,不放 jedi-file-upload、不塞 jedi-common)→ 看雛形「不要有未加密下載的選項」(D5 v2 拿掉使用者可選)→ 「要讓 user 選嗎?業界怎麼做?PM 意思都要加密」(v3 定案:使用者永遠不能選、管理員開關預設開、關閉三道警示)→ 「都照建議,落 design 開卡」。
- 推翻過的:v1 三選一含「使用者可選」→ v2 兩檔 → v3 一個開關預設開。首腦曾建議「寫死強制」後自己重算推翻(e2e/教育訓練、客戶 DLP、匯出餵別系統三種情境要正規出口)。
- 雛形 bug:對話框遮罩蓋住頂部切換橫幅,決策者點不到其他畫面;改遮罩只蓋畫面區、橫幅 sticky 置頂。
- 開卡陷阱:agent-workshop 的
scripts/notion_case.py 預設指向另一個「任務清單」(Agent Workshop 自己的,64 張卡、無 Repo 欄);Guidant AI 的卡在 23c346da-4cd0-8041-955e-000bb6976dd2。本案 patch_workshop_fields.py 明確覆寫 nc.DATASOURCE_ID;建卡走 BE 本地 scripts/notion_create_case.py(它旁邊的 notion_case 指對庫)。
- 拆卡斷言抓到一處:D1 依賴 F3 卻同批,移批 5。
- Commits:529e801b1 analysis、196eb9f7c 討論稿 v1+雛形、d4b2a2902 雛形修遮罩、6ae27ec48 v2、82bad11b0 v3、761c7fd24 design+cards.py、(本次)開卡與卡號回填。
- Notion:母卡 CM-3223;子卡 CM-3224 P1 套件(批1)、CM-3225 B1(批2)、CM-3226 F1(批2)、CM-3227 B2(批3)、CM-3228 F2(批3)、CM-3229 A1(批3)、CM-3230 F3(批4)、CM-3231 D1(批5)。
- 下一步:決策者在工作坊狀態頁「新增工作坊」選 CM-3223 派批 1。
§2
2026-10-29 首腦:母卡層總驗 → 三支套件發版 → 補批 6 兩張卡
- 八張卡(CM-3224~3231)工作坊首腦已逐卡驗到「驗收通過待確認」;本棒做母卡層抽查:四個 repo 工作區
ws-CM-3223 都乾淨、commit 在;BE helper 測試 117 過(兩支 capabilities_are_seeded 紅是工作區沒掛 seed、主資料夾同測試綠,非本案);Agent 工作區全量 1674 過;套件 jedi-file-protect 38 過、jedi-masking 25 過;FE 兩支 spec 綠、新增 border-left 為 0;DEV 已有 28 筆 FILE_DOWNLOADED 稽核、log/app.log grep X-File-Password 為 0。
- 沒驗到、留給決策者:GUI 開檔(Word/Acrobat/7-Zip 跳密碼框)這台機器沒有 GUI 軟體;Agent 真機下載(Agent 要註冊才起得來,小弟與首腦都只用 test client 打路由)。
- 總驗抓到三個缺口,開批 6 補卡:①主系統收 Agent 稽核事件的白名單
_agent_console_audit._FIELDS 沒有 encrypted,Agent 那邊是加密還是明文下載主系統稽核頁看不到(A1 首腦復核已記、沒人開卡);②D5 的「總覽常駐警示」沒做(只有安全政策頁自己的警示);③D5 的「稽核頁每筆下載標未加密」沒做(i18n 預留了 key 沒人用)。D1 第 2 輪為了「文件只寫現況」把②③從 SPEC 與手冊拿掉了,B3 做完 F4 再補回。→ CM-3280 B3(BE,sonnet/low)、CM-3281 F4(FE,sonnet/medium),同批。
- 套件發版(決策者「可以的話就發套件版本」):jedi-file-protect 0.1.0 首發、jedi-iam 1.9.0→1.10.0(新鍵是功能,進中版號)、jedi-masking 0.1.0→0.1.1(jedi-log 與 Agent 都釘
<0.2,不能進 0.2)。build 到 scratchpad 乾淨資料夾、開包 grep 驗三處改動都在、再 publish;Nexus 查到三版都上架。套件 repo 工作區 commit ae95ad61。
- 釘版:BE 主資料夾
pyproject.toml jedi-iam 1.10.0、加 jedi-file-protect 0.1.0、dev path 註解區補一行,poetry update 三支,驗 import 在 site-packages、無 .pth;commit 34206718e。Agent 工作區 poetry add jedi-file-protect、升 jedi-masking 0.1.1;commit 4df889e。四個 repo 的 workshop.md v4 各自 commit。
- 踩到:BE session 的 shell 帶
VIRTUAL_ENV,到套件工作區跑 poetry install 把 editable 套件裝進 BE venv;拔掉後重做。記憶 feedback_poetry_in_worktree_respects_virtual_env_of_session。
- jedi-iam 測試紅燈是基線既有:
test_plugin_layout::test_frozen_urls_match_actual_mount 與五支 collection error 在 feature/FR-139 主資料夾同樣紅,與本案無關,沒動。
- 未完,等決策者:工作坊「合回」四個 repo 的
ws-CM-3223 到 feature/FR-139(合回後重啟 8000 才吃到新程式與新套件);派批 6;母卡 Done;push;STG/POC 上版。
§3
2026-10-29 首腦:四 repo 合回 feature/FR-139 + 重啟驗證
- 決策者「你把它合回來呀」:四個 repo 主資料夾
git merge --no-ff ws-CM-3223。套件 94841065、Agent 0d30cf5 無衝突;BE 5ae53b390 衝突一處(agent-console.md 變更紀錄表 FR-166.1 與 FR-169 同位置各加一行,兩行都留);FE 0aeefd06 衝突一處(console/views/Files.vue import 區,FR-166.1 F2 的 canDownload/downloadOnly/ReportPreviewDialog 與 FR-169 F3 的 useProtectedDownload、拿掉 saveBlob,兩邊都留,檔內各符號皆仍在用)。合回後四 repo ws-CM-3223 領先 0。
- 重啟 8000(只殺核過的 57425 與其 multiprocessing 子行程 57505;worker 41809 不動)。release 字串帶合回 commit。實打:
GET /system/file-download-protection 回 enabled true;POST /governance/risks/export 無 header 回 400 GRC_400190;帶 X-File-Password 回 200、xlsx is_encrypted True、用同密碼解回 PK 開頭 21,344 bytes、header Cache-Control: no-store/X-File-Protected: 1/X-File-Needs-7zip: 0;稽核多一筆 encrypted=True;log/app.log grep 密碼 0。守衛測試+helper 128 過。
- 工作區
.worktrees/CM-3223 保留:決策者會派批 6(CM-3280、CM-3281),工作坊會疊在 ws-CM-3223 上做,做完再按一次「合回」。
- 等決策者:派批 6;母卡 Done;push 四 repo;STG/POC 上版。
§4
2026-10-29 首腦:批 6 驗收 → 合回 → 十張卡收齊
- 批 6 兩張卡工作坊首腦各驗兩輪通過。本棒母卡層抽查:B3
_FIELDS 加 encrypted、_clean 只對該欄放行 bool 轉字串;sink 測試 17 過、突變(拿掉該欄)1 紅、還原。三處文件 grep「稽核事件頁每筆」0、兩份手冊一致。F4 FileProtectionOffBanner.vue 掛 AppLayout、條件 store 值為 false 且持安全政策讀取能力點;用 SSR 渲染字串驗三種狀態(false 顯示/true 不顯示/null 不顯示)通過;isUnprotectedDownload 殘留 0;新檔 border-left 0。
- D5 第三道「畫面上標未加密」決策者裁示不做(F4 復核時):系統沒有稽核事件頁,稽核事件只出到診斷包與 log 轉發;UserLogs 讀的是 HTTP 請求流水表
api_logs,比對不到 system_logs 的稽核。開卡時把 UserLogs 當稽核事件頁是首腦寫錯。
- FE 工作區 vitest 那條 i18n 守衛紅燈是工作區落後 feature:五句都是 CM-3279 在 feature 修的、ws 沒碰那五檔;合回後 FE 全跑 367 全綠。不是本案問題,記下免得下次又追。
- 合回:BE 9a909e711、FE e9a521e5,零衝突;兩 repo ws 領先 0。BE 測試 145 過;8000 重啟帶 9a909e711。
- 還沒驗到:真機 Agent 下載後主系統稽核看到
encrypted=true——DEV 唯一一台 Agent(1126d080)今天 18:58 送的事件還沒這欄(當時主系統沒收、Agent 也未必是 A1 版);要等 Agent 以合回後的程式部署再看。GUI 開檔與橫幅實看同前。
- 等決策者:母卡 Done;四 repo push;Agent image 出包(A1 回寫記的 Nuitka 收 py7zr/msoffcrypto/reportlab 檢查);STG/POC 上版;出包前基線重產(seed 守衛兩顆能力點缺 04-seed-core.sql,FR-166.1 遺留)。工作區
.worktrees/CM-3223 可由工作坊「結案」移除。
§5
2026-10-29 首腦:決策者實測證據附件沒加密 → 直修 → 全站出口盤點補卡
- 決策者截圖證據區塊按下載直接開。根因:開卡時範圍定成「主系統 16 支匯出 route」,D1 把 jedi-file-upload 列「不動」,套件自帶的
GET /file/download/<uid>(證據、程序書、模組框架文件池、前置資料、問卷附件、意見回饋附件)整條漏接;FE 走 signedDownloadUtil.openFileDownload 換 ?st= 開新分頁,帶不了密碼 header。十張卡驗收與合回都沒抓到,因為驗的都是匯出端點。
- 直修(決策者「你這邊直接修」):jedi-file-upload 1.4.0→1.5.0 加選填
FileUploadAdapters.download_responder、runtime.send_download、下載 route 改走它(未注入照舊 send_file;拿掉 ?attachment=);contract 測試+突變。BE core/plugins/_file_upload_download.py responder 把路徑/BytesIO 讀成 bytes 交 send_protected(source="upload_file"),file_upload.build_adapters 注入;helper 測試三條。FE useProtectedDownload.downloadFile(fileUid, name),12 處改接,fileDownloadUrl/openFileDownload 刪除,意見回饋兩頁的手刻 axios blob 一併收掉。
- 驗證:套件 25 過(突變紅);BE 131 過;FE 367 過、build 過;DEV 實打截圖那兩個檔:docx 無密碼 400、帶密碼加密可解;png 包 header 加密 7z;稽核 source=upload_file;log 無密碼。發版 1.5.0 推 Nexus、BE 釘版重啟再打仍對。commits:套件 13e0de4a、FE cfd311d9、BE 84a23bf41。
- 全站出口盤點(grep 主專案+已裝 jedi 套件的 send_file/Content-Disposition、FE blob/window.open/DOWNLOAD_FILE):還漏三支人用機敏匯出——jedi-api-log 操作日誌、jedi-issue 意見回饋匯出、jedi-task-platform 任務批次 Excel。不接(理由):jedi-iam 匯入範本與 TOTP QR、jedi-asset 裝置範本、jedi-evidence-classification inline 預覽、jedi-detection 報告(主系統 Agent 報告端點已接)、BE
agent_file/agent_vulndb(Agent 機器對機器)、OSCAL 框架 JSON(公開)。→ 批 7 P2 CM-3286(套件掛點)、批 8 B4 CM-3287(主系統注入+FE 三處)。
- 教訓進 memory
feedback_download_exits_enumerate_all_routes_incl_packages_before_scoping:橫切需求開卡前固定三條 grep,每條出口都要在「接」或「不接(理由)」其中一邊。
- 等決策者:派批 7;母卡 Done;四 repo push;Agent 出包;STG/POC。
§6
2026-10-29 首腦:zip 炸彈修正 → D3 改判 7z→AES-256 zip
- 自動資安檢視指出上傳檔走
send_protected 會被自動拆 zip(原前提是只有自產 zip 會進來)→ 加 unzip 旗標,responder 傳 False;測試+突變。commit fa95445f1。
- 決策者「不要用 7z 請用 zip,我剛剛下載不能解壓」:講明 AES zip 檔名外露、內建解壓一樣開不了、ZipCrypto 等於沒鎖;決策者選 AES-256 zip。
- 改動:套件 archive 換 pyzipper(WZ_AES 256、ZIP_DEFLATED、禁 ZipCrypto)、副檔名 .zip、
needs_7zip 欄位名與 X-File-Needs-7zip header 沿用(語意改「要裝第三方解壓工具」),0.2.0 發版(e1c18c23);BE mimetype application/zip、測試改 pyzipper 驗、釘版 0.2.0;Agent mimetype 與測試、相依上限放寬到 <0.3(6673c97、lock commit);FE 對話框文字與 fallback 副檔名(37a04cce);SPEC 七頁與手冊兩份文字;design D3 改判、README 結論。
- 驗證:套件 37 過(突變:拿掉 WZ_AES 紅、256→128 紅);BE 132 過;Agent 19 過(真裝 0.2.0);FE 367 綠、build 過;DEV 實打 png 下載回 application/zip、
zipfile 列得出檔名、無密碼讀內容 RuntimeError、帶密碼解出 PNG;log 無密碼。
- 已知代價寫進文件:zip 檔名清單明文(檔名不要放機密);Windows/macOS 內建解壓打不開 AES zip,對話框與手冊都改成提醒裝 7-Zip/WinZip/Keka/The Unarchiver。
- 決策者問「檔名外露是什麼意思」,解釋(zip 檔名清單不用密碼看得到、內容要密碼)後裁示:「畫面上都有了,有檔名也不能幹嘛,用原檔名.zip 就好」。首腦提的兩案(zip 內檔名改
file-<時間戳>-<序號>.<副檔名>+manifest 對照;只改外層檔名)都不做。現況即終局:外層 原檔名.zip、裡面原檔名、內容 AES-256。
- 決策者點名「故意不思考的狀況很嚴重」:這一輪三次設計(7z→zip、檔名中性化、副檔名)都是先動手再被問出盲點。教訓:改容器格式這種對外可見的決定,動手前先把「使用者拿到會看到什麼、哪一層被鎖、哪一層沒鎖」三句講清楚給決策者裁,再改。
- 決策者「壓縮檔類不要顯示副檔名」:包 zip 的單檔外層檔名去掉原副檔名(
截圖.zip,不是 截圖.png.zip),裡面保留原檔名;Word/Excel/PDF 照原檔名。jedi-file-protect 0.2.1 發版(a5c23e37)、BE 釘版、Agent 升版與測試(7119048)。DEV 實打:X-Filename …截圖.zip、裡面 …截圖.png、AES strength 3(256)、密碼可解。
- 踩到:突變測試後用
cp 還原 archive.py,mtime 沒變、舊 pyc(128 位元版)繼續被 import,一度量到 AES-128 以為套件寫錯;清 __pycache__ 後 256。已發版 wheel 與 BE venv 實量都是 256,線上無影響。以後突變測試用 git checkout -- <檔> 還原,不用 cp。
- 對話框:決策者看畫面「上下說明留一個或合併」→ zip 情況合併成一個橘框,刪
hint_7z(FE f48b57f0)。
- 決策者「還是有問題,給我 prompt 我請下個首腦繼續修」:沒說是什麼問題,本棒結束。STATE §2 寫明下一棒先問清楚再動。
§7
2026-10-29 首腦(第二棒):「還是有問題」=兩件事——Agent 本機登入(不歸本案)、PDF/Office 預覽哭臉(FR-166 回歸)
- 決策者說明「還是有問題」是:①本機 Agent 主控台登不進去 ②docx 無法預覽,接著補「直接預覽 PDF、Excel、docx 都一樣」並附 Chrome 哭臉截圖。
- ①Agent 登入:決策者裁示「不要查,我請另一個 session」,本棒停手不追。查到一半的線索留一行:Agent log 顯示
console login rejected: ticket scope [...] is empty or unknown,PID 18931 是 10-28 21:28 起的,download-files 那個 scope 是 10-29 02:29 才加進 CONSOLE_SCOPES,跑的程式比票舊——只是線索不是結論,給另一棒自己驗。
- ②預覽:後端實打
/file/pdf-preview/ 三個檔(netdiag PDF、CRA docx、control-mapping xlsx)都回 200 application/pdf inline、未加密,LibreOffice 轉檔正常,不是 FR-169 弄壞的。根因在 FE FilePreviewPane.vue:44f2e5f7(FR-166 CM-3198,10-28 晚)加的 :sandbox="sandboxed ? '' : undefined"——真瀏覽器 iframe.sandbox 是 DOM 屬性,Vue 走 el.sandbox = undefined 被字串化成 sandbox="undefined",等於全禁 sandbox,Chrome PDF 檢視器不畫。
- 為什麼十張卡+昨晚實機都沒抓到:jsdom 的 iframe 沒實作
sandbox 屬性,Vue 在測試裡改走 setAttribute、undefined 正確移除,「PDF iframe 不帶 sandbox」那條斷言一直假綠;實機只開過 HTML(sandboxed=true)沒開 PDF。教訓:DOM 屬性與 attribute 的分歧 jsdom 測不出來,涉及 iframe/media 這類有專屬 DOM 屬性的元素,要在真 Chrome 開一次。
- 修法:改
:sandbox.attr(強制 setAttribute)。HTML 報告預覽仍帶 sandbox=""、後端 CSP sandbox 不動,PDF 回到 10-28 前狀態、沒放寬。Pane spec 補瀏覽器形狀的 HTMLIFrameElement.prototype.sandbox stub+兩條斷言;突變(拿掉 .attr)紅;vitest 375 綠、build 過。FE commit 72ed484c。決策者手測預覽 OK。
- 決策者指示「不用做太多測試,我會手動測試」——後續只做修正與必要守衛測試。
- 踩到:突變後
git checkout -- <檔> 把自己未 commit 的修正也一起還原了(還原的是整個檔不是只有突變那行),重套一次。要突變未 commit 的改動,先 commit 再突變,或用 sed 反向改回。
§8
2026-10-29 首腦(第二棒):PDF 預覽藏瀏覽器工具列 → 文件收尾
- 決策者看到 docx 轉 PDF 的預覽上方有 Chrome 內建檢視器的下載/列印鈕,問能不能擋。這是 FR-169 的真缺口:有預覽權的人按那顆鈕拿到的是沒密碼的 PDF,繞過加密也繞過 FR-166.1 F2「預覽歸預覽、下載看能力點」。
- 先講三句再動:藏工具列一行(擋順手點,擋不住右鍵/Ctrl+S,Firefox/Safari 不理);pdf.js 自繪一張卡(全擋畫面操作,擋不住開發者工具);後端轉圖片不建議(截圖本來就擋不住)。決策者「先加那一行」。
- 做法:主站
FilePreviewDialog 與主控台 console/components/ReportPreviewDialog.vue 的 PDF blob 網址加 #toolbar=0;共用 FilePreviewPane 加 @media print { .fp-body { display:none } }。HTML 預覽不加片段。第一版把判斷放在 Pane 猜網址,把主站 HTML 的 st 網址也加上了,改成由呼叫端決定。三條既有 PDF src 斷言跟著改;vitest 375 綠、build 過。FE commit 03e6acfb。
- 決策者「Agent 你沒改到,還是因為沒重啟」:主控台走
dist-console 靜態包(Agent 從 AGENT_CONSOLE_ASSETS_DIR 直接讀目錄、不入版控),停在 20:45 的舊包,sandbox 修正與工具列都沒進去。npx vite build -c vite.console.config.js 重 build 後決策者實看 OK,Agent 不用重啟。教訓:改到 src/components/common/file-preview/ 或 console/ 的東西,主站重整就吃到、主控台要重 build dist-console;回報時要分開講。
- 文件:共用檔案預覽視窗 SPEC(變更紀錄+規則 3、4)、agent-console SPEC 執行紀錄一句、兩份手冊加「線上預覽不用密碼但拿不到檔」一節、design 變更紀錄兩列(D3 補 0.2.1、D7 補)+D7 定案改寫+驗收第 9 條、README status/結論/需求討論紀錄三筆、STATE。
- 決策者「準備收尾」:收尾類動作(母卡 Done、push、SUMMARY、memory)等令。
§9
2026-10-29 首腦(第二棒):批 7~8 首腦直做 → 三支套件發版 → 收尾
- 決策者問批 7、8 是什麼、要不要做。首腦實查三個出口仍
send_file 明文,判斷要做(操作日誌是全站 API 請求紀錄,最敏感)。決策者「你這邊直接做」、「發吧,做完就發,然後這邊可以收了」、「最後再 push 一下」。
- 套件(
aad916f4、5230800d、9cda814e):jedi-log 操作日誌、jedi-issue 意見回饋、jedi-task-platform 任務批次匯出照 jedi-file-upload 1.5.0 形狀加 download_responder+send_download;jedi-log route 事後補的 X-Filename/expose 改 setdefault(直接指派會蓋掉宿主設的加密後檔名與 X-File-Protected)。發版 jedi-log 1.4.0、jedi-issue 1.5.0、jedi-task-platform 1.5.0,開包驗過再 publish。
- jedi-log 1.4.0 會連帶發出源碼裡本來就沒發過的 1.3.7(jedi-masking 薄殼化),相依 jedi-masking 0.1.1(早已上架);jedi-log 自己的跨套件 import 守衛因此早就紅,白名單補
jedi_masking。BE test_module_boundaries 也登記 jedi_masking(層 1.5、能力點豁免、頂層單檔白名單)。
- BE(
b16f053a5、c9bbd014f):_file_upload_download.responder_for(source, unzip=False),api_log api_log_export(unzip=True,自產 zip 重包成一個 AES zip,裡面 xlsx 不雙重上鎖)、issue feedback_export、task job_export;釘三支新版。FE 不用改:三處 F2 就走 useProtectedDownload,只是後端沒收。
- DEV 實打(先 pip -e、釘版後再打一次):三支都是無密碼 400 GRC_400190、帶密碼 200 加密檔、稽核 source 正確、log 無密碼;pytest 133 過。
- 踩到:BE working tree 有另一個 session(FR-166.1 首腦)未 commit 的 jedi-detection path 改動在 pyproject/lock。釘版時先存 patch+備份、
git stash 那兩檔、在乾淨 HEAD 上 update+commit、再 pop;pop 撞 lock 的 content-hash 衝突,手解後 poetry lock 重算、git restore --staged 讓兩檔回到對方未 commit 狀態、jedi-detection path 重裝回 venv;stash@{0} 保留未 drop。對方事後來訊說那個 path 已不需要、可以還原到 HEAD 並 drop stash——交給對方自己收或決策者裁。
- 文件:三頁 SPEC(任務批次、意見回饋、操作日誌;操作日誌那列順手改掉過期的「🔴 無認證」)、README、design、STATE。
§10
2026-10-29 首腦(第二棒):系統回饋頁白畫面——cfd311d9 漏 import
- 決策者「公告功能整個壞掉」,貼系統回饋表單網址與主控台截圖:
ReferenceError: useProtectedDownload is not defined(SystemFeedbackForm.vue:25)。後端端點全部 200,問題在 FE。
- 根因:cfd311d9(證據附件補洞,12 處改接)在系統回饋表單與檢視兩頁加了
useProtectedDownload() 呼叫卻沒 import。vite build 不檢查未宣告識別字、vitest 沒掛這兩頁,所以 build 與全量測試都過,打開頁面才炸。全站掃過只有這兩頁漏。
- 修:兩頁補 import;新增守衛
src/__tests__/protected-download-import-guard.spec.js(有呼叫卻沒 import 就紅,略過註解行),突變拿掉 import 會紅並指名檔案。FE 257b52dc,已 push。
- 教訓:大批改接呼叫端(一次改十幾個檔)時,build 綠不代表每頁都開得起來;改完要 grep「有呼叫卻沒 import」,或靠這支守衛。
§11
2026-10-29 首腦(第二棒):收尾
- 決策者問目前可設定的下載能力點有哪些,首腦列出 7 顆(任務證據、安全計畫佐證、稽核匯入原稿、AI 分類暫存、檢測報告、意見回饋附件、Agent 下載檔案)與各自用在哪些畫面;指出「稽核匯入原稿」前端沒有畫面引用,按鈕不會依它隱藏、只靠後端 403。只回報,未改。
- 決策者「這邊可以收 Done 了」:Notion CM-3286、CM-3287、母卡 CM-3223 改 Done(前十張早已 Done)。README/design/STATE 改已收尾;STATE §3 依決策者裁示三項未驗當作驗過,§4 只留上版事項。
§12
2026-10-29 首腦(第二棒):收 Done 後的三個回報
- SBOM 頁一開就跳缺少密碼:決策者以為是匯出報表,實為頁面載入時 SBOM 檢視器打
/files/sbom 拿 JSON 解析顯示,B2 把這支整條改加密。講三句、決策者同意後:後端 inline=1 且 kind=sbom 回純 JSON(inline、nosniff、不給檔名),其他 kind 帶 inline 照舊加密;前端檢視器帶 inline。BE 9d0d5f380、FE 759f8af6。自動資安檢視指出「client 旗標決定不加密、不記稽核」——同證據預覽的既有取捨、決策者已知,未改。
- 責任分工 Excel 也不要加密:首腦查出匯入端全專案沒有能解密加密 xlsx 的,七支「匯出再匯回」樣板都有同一問題;提「類別設定、證據強制」方案。決策者裁示:責任分工設定、控制項對照、任務批次先不加密,設定功能先不做。新增
send_unprotected(照樣記 FILE_DOWNLOADED encrypted=false),三類改走它(控制項對照 4 個出口共用 _download 一起改);前端三處 protect: () => false。BE 32d3c42b1、FE 22748f7a。DEV 實打三支不帶密碼 200 明文、稽核 encrypted=false、沒登入 401。
- 決策者問「是不是只有前端擋、知道路徑就能下載」:不是,加密在後端,直接打網址不帶密碼 400、帶了拿到的是加密檔。真正知道路徑就拿得到明文的只有預覽端點(證據 docx 預覽回未加密 PDF),這是 FR-169 一開始就有的取捨;要堵的兩個方向(預覽也要下載權限/預覽改圖片或 pdf.js 自繪)已回報,等決策者裁。