Skip to Content
變更紀錄

變更紀錄

這份手冊對照 teamsync-backend master 撰寫,稽核時使用分離的唯讀 worktree。

釘選值
Commit9d7e0c69ad99fe5ff9becd647a07451c6adbf07b
主旨chore: bump version to 5.22.1
版本tag v5.22.1 — 2026-10-09 釋出
日期2026-10-09
設計契約docs/architecture/edge-workers-plan.md(V2-only,2026-08-14;之後擴充了退役、共用位置路由與地端 provider)
Routersrc/routers/private/modules/edge_workers/server.py(base /private/module/edge-workers),同一套件內另有 service_accounts.py、service_account_bindings.py 與 starters.py
Schemassrc/schemas/edge_workers.py、src/schemas/edge_worker_company_admin.py、src/schemas/edge_worker_secrets.py、src/schemas/edge_worker_service_accounts.py、src/schemas/enums.py
領域元件src/components/edge_workers/(contract、builder、gateway、cloudflare_api、artifacts、assertions、release_generation、retirement、orphan_report、providers/)
持久層src/database/models/edge_worker.py、src/crud/edge_workers/、src/crud/service_accounts.py
背景任務src/tasks/edge_worker_{deploy,artifact_cleanup,control_audit}_task.py、src/workers/pubsub_consumer.py、src/server.py 內的復原與 host 調節迴圈
Dependenciessrc/dependencies/edge_workers.py、src/dependencies/service_accounts.py
Cloudflare 平台 + CLIedge/department-workers/(dispatcher、builder、runtime template、teamsync-worker CLI、專案範本、starter pack)
地端edge/edge-host/、src/components/edge_workers/providers/onprem/、scripts/setup-edge-workers-onprem.sh、scripts/edge-workers/、docker-compose.edge-workers.yaml、docs/deployment/on-prem/

若某頁與上述程式碼樹不一致,以後端原始碼為準 — 請回報讓文件被修正。

2026-10-09 — production v5.22.1:搬移完成後若已再部署則拒絕回滾、新 Worker 建立於共用位置、移除已退役的腳本

釘選從 ceee9a325d(v5.22.0)移到 9d7e0c69ad99fe5ff9becd647a07451c6adbf07b,即 tag v5.22.1(chore: bump version to 5.22.1,2026-10-09 08:46 UTC)。稽核範圍涵蓋兩個版本之間的 3 個 commit,其中 2 個變動 Edge Workers(PR #2174 與 #2175)。對作者與串接方而言的變更:

  • 搬移完成後只要已接受過部署,該搬移的回滾就會被拒絕(#2174)。平台維運者對已完成搬移所做的回滾,若搬移完成後曾接受過任何部署(已上線的、失敗的,或仍在執行中的),現在會回 409 migration_completed_rollback_requires_operator_recovery;在 5.22.0 它會被接受,並讓 Worker 需要平台維運者處理。這個拒絕不會更動任何內容,並告知提出回滾的維運者改用針對目前部署的維運者復原程序。沒有後續部署的回滾仍會被接受。頁面:搬移 Worker(先前對「後續部署之後回滾」的說明已被取代)。
  • 在雲端,新 Worker 的第一次部署現在會把它放在平台的共用位置(隨本版推出;由 #2174 預作準備)。已部署過的 Worker 維持原本的位置;URL 與 API 都不變;不需要任何動作。
  • 已退役 Worker 的平台腳本會自動移除(#2175),於退役後一段時間才進行;不需要任何動作。

稽核備註 — 已檢視而排除:第三個 commit 只是升版號。依設計不予記載:已完成搬移的維運者復原程序、新 Worker 的放置方式、已退役腳本的移除方式,以及測試與 CI 的變更。

2026-10-09 — production v5.22.0:10 分鐘的就緒等待、builder 政策 v2.10、連同資料搬移 Worker

釘選從 172a7f80bd(v5.21.0)移到 ceee9a325d17d08a33e6c5bd94b9ecc3d1c84112,即 tag v5.22.0(chore: bump version to 5.22.0,2026-10-09 02:44 UTC)。稽核範圍涵蓋兩個版本之間的 24 個 commit,其中 8 個變動 Edge Workers(PR #2160、#2162、#2163、#2165、#2169、#2171、#2172 與 #2173)。對作者、串接方與維運者而言的變更:

  • 部署最多可能要 10 分鐘才回報就緒(#2173)。上傳之後,部署任務現在最多等 600 秒(先前是 60 秒),等新的 release 在簽章控制通道上回應唯讀的 access_policy.get 探測。在較新的 runtime 上重建既有的 Worker,可能要好幾分鐘才回報就緒;部署現在最多等 600 秒。在 600 秒內回應的 release 現在會以 completed 結束,更慢的仍以 uncertain 收場。輪詢仍是 1 → 2 → 4 → 5 秒;截止點之後不會再啟動探測,每次探測在 40 秒或截止點(以先到者為準)被中斷(5.21.0 的頁面曾說最後一次探測可能稍後才結束);每次探測前後,任務都會重新驗證它的資料庫租約,失去租約就停止。等待期間票證讀作 leased 或 deploying,Worker 是 paused(閘道通道的呼叫得到 404)。teamsync-worker deploy --wait 的預設值仍是 240 秒,因此可能在票證結算前就放棄:請把 --timeout-ms 調到大於 600 000,或改為輪詢票證。頁面:版本與部署、部署與輪詢、公司管理員、限制一覽、錯誤、背景任務、CLI、維運總覽。
  • Builder 政策 department-worker-project-v2.9 → v2.10(#2162、#2169)。新的建置會得到新的 release generation,並回報 v2.10(GET /starters、build_policy_version)。v2.10 加入了讓平台維運者可以連同 Durable Object 狀態一起搬移 Worker 的 runtime;handler 契約、路由與回應格式都沒有改變,回執中的 builderPolicy 仍是 19 個欄位。較早建置的修訂版保留自己的政策、持續提供服務,但在部署 v2.10 修訂版之前無法被搬移。CLI 壓縮檔現在也包含 migration-runtime.mjs。頁面:提交管線、搬移 Worker、列舉與狀態、範本與原始碼下載,以及每個提到目前政策的頁面。
  • 連同資料把 Worker 搬到另一個 Worker 位置(#2160、#2162、#2163、#2169、#2171、#2172、#2173;由平台維運者執行)。平台維運者可以把既有的 Worker 連同它的 Durable Object 狀態,搬到共用的 Worker 位置。串接方不需要做任何事:URL、路由、票證、金鑰與 token 都不變。讀者能觀察到的是:一段短暫的暫停,通常遠不到兩分鐘,期間兩條通道都回 503 migration_fenced(請以退避方式重試;程式碼沒有強制任何上限);以及會先讀取 Worker 狀態的管理呼叫 — 讀取、操作設定與金鑰、機密寫入、部署 — 會回各自慣用的修訂版過期 409;在搬移完成、回滾或放棄之前,部署回 409 worker_migration_in_progress(Worker 已持有逐操作設定或請求帶有 operation_settings 時,則是 503 Department Worker control change is unavailable),其他有稽核的變更回該 503,刪除該部門回 400 worker_migration_state_retained;凍結之後才失敗的搬移會讓 Worker 維持凍結,直到維運者完成搬移或把它回滾,回滾會恢復 Worker 被凍結當下的狀態,之後的寫入不會被併回。搬移之前,平台可能會在最新的 runtime 上重建 Worker 目前的修訂版:它的歷史中會出現一個新的修訂版與部署,程式碼沒有改變,而在重建就緒之前,呼叫可能短暫失敗。dispatcher 會採用後端為已搬移 Worker 記錄的啟用(維運者的啟用對照表中的項目仍然優先)。新頁面:搬移 Worker。頁面:架構與信任邊界、調度協定、持久儲存、呼叫 API、錯誤、退役、平台佈建、維運總覽。
  • 後端記錄每個 Worker 由哪個位置提供服務(#2160、#2169)。在雲端上,每次部署都會儲存其 release 的服務位置;一般部署繼承它,且不能再改變它。後端在針對這類 Worker 的呼叫上,把它簽進斷言的 serving_target claim,但不一定每次呼叫都會簽入(5.21.0 的頁面曾說後端從不送出這個 claim)。沒有任何回應欄位會報告它。可見的效果是:後端無法驗證位置時回 409 worker_serving_target_unavailable(部署:Worker deployment target cannot be verified;有稽核的控制變更:Department Worker control requires a verified serving-target attestation)、503 Department Worker serving target is unavailable,以及部署票證的 error_code legacy_serving_target_unavailable、deployment_target_unavailable 與 deployment_target_release_changed。在本版之前部署的 Worker,需要平台維運者驗證它的位置;在那之前,部署與有稽核的控制變更都會回上述 409。復原掃描現在認領共用位置加上環境自己的舊有位置,不再認領舊有的 "" 資料列。頁面:錯誤、部署與輪詢、版本與部署、架構與信任邊界、調度協定、背景任務、環境變數、資料庫模型、退役。
  • 維運者:dispatcher 部署需要 EDGE_WORKERS_R2_BUCKET(#2163)。staging 與 production 的 dispatcher 部署現在要求它(後端已在使用的 edge 產物 bucket)。頁面:平台佈建、環境變數。

本版讓早先頁面中不再正確的說法(本次修訂已更正):60 秒的就緒等待與「最後一次探測可能稍後才結束」;「後端從不送出 serving_target claim」以及該 claim 恰為 {dispatch_namespace, routing_epoch} 的形狀;把啟用對照表當成唯一的釘選方式、其餘一律依固定查找順序;outbox 的範圍規則(資料列的範圍現在是 Worker 的服務位置,舊有的 "" 資料列不再被認領);退役頁面的單一 namespace 寫法;資料庫模型頁的「五張表」;CLI 壓縮檔的檔案清單;Worker 從未到達之位置的退役確認;「依精確 id 的租約維持全域」;「test 部署會略過 dispatcher job」的說法;以及每一處「目前是 v2.9」。

稽核備註 — 已檢視而排除:兩個版本之間的 24 個 commit 中,8 個變動 Edge Workers;其餘 16 個變動其他模組(Custom Tables、Sandbox、server 與 Kubernetes 管線)或只是升版號。這 8 個之中,#2165(開發與 CI 基礎設施)不予記載;#2171(給維運者的 provider 拒絕細節)只改變維運者看到的內容;#2172(已搬移 Worker 的實體腳本名稱)只記載於調度協定頁,其餘只改變維運者看到的內容;#2169 與 #2173 強化搬移的復原,#2169 另外加入有稽核控制變更的 409,#2173 則帶來上述就緒等待的變更。依設計不予記載:搬移中只與維運者有關的機制,以及開發環境。這些說法背後的部署筆記與程式碼若有出入,以程式碼為準。

2026-10-08 — production v5.21.0:逐操作存取、Worker 機密、服務帳號、Worker 退役、共用位置路由與地端部署

釘選從 70862ceae7(v5.10.11)移到 172a7f80bdf4dbdffdc018eb08bfa42c62bb485c,即 tag v5.21.0(chore: bump version to 5.21.0,2026-10-08 11:07 UTC)。「Release & Deploy to GCP (production)」工作流程於 2026-10-08 成功結束;其 edge-dispatcher job 發現 dispatcher 與原始碼不一致,重新部署後讀回為一致。稽核範圍涵蓋 1 848 個 commit、15 個版本(5.10.12–5.10.14、5.11.0–5.20.0、5.20.1 與 5.21.0)。每一項都標示最早包含它的版本(對其合併 commit 執行 git tag --contains)。對作者、串接方與維運者而言的變更:

  • 逐操作的進站存取與操作 API 金鑰(builder 政策 v2.8;#1712,v5.13.0)。新路由 GET/PUT /worker/operation-settings 與 POST/DELETE /worker/operation-settings/{operation_id}/api-key。在 v2.8 release 上,公開通道依符合的操作、在路由比對之後才准入:操作可繼承 Worker 層級政策,或覆寫模式與 CIDR,並可擁有永遠不會退回 Worker 層級金鑰的 API 金鑰。輪替 Worker 層級金鑰只剩舊版 release 可用(409 worker_wide_key_legacy_only);設定尚未就緒的 release 回 403 operation_settings_pending;成員 OpenAPI 帶有逐操作的 security 與 servers,以及根層的 x-teamsync-operation-settings-state;POST /worker/deployments 可帶選用的 operation_settings,而部署若撞上另一個進行中的部署或設定變更,現在回的是有代碼的 409 deployment_in_progress,不再是舊的純字串。更新的頁面:逐操作存取、管理逐操作存取、存取模式、管理存取政策、版本與部署、部署與輪詢、呼叫 API、端點、Schema、錯誤、限制一覽。
  • 僅可寫入的 Worker 機密(builder 政策 v2.6 與 v2.7;#1711,v5.13.0)。GET /worker/secrets 與 PUT/DELETE /worker/secrets/{name};handler 程式碼以 await context.secrets.get(name) 讀取。名稱須符合 ^[A-Z][A-Z0-9_]{0,63}$ 且不得以 TEAMSYNC_ 開頭;單一值最多 64 KiB,一個 Worker 最多 256 筆、合計 16 MiB。值永遠不會被回傳、後端只保留加鹽摘要、變更不需重新部署即生效,而把 v2.6 之前的 release 部署到 v2.6 或更新的 release 之上,會清除全部機密。CLI 的 dev 指令會讀取 .teamsync/dev-secrets.json。更新的頁面:Worker 機密、管理 Worker 機密、執行期設定、管理執行期設定、CLI — teamsync-worker。
  • 部門服務帳號(builder 政策 v2.9;#1713、#1718、#1729,v5.13.0)。Worker 用來登入的平台自有虛擬使用者(EdgeWorkerSA-…):七條部門路由加上七條公司層級的對應路由、透過操作設定建立的綁定(service_account_id、default_service_account_id),以及 handler 程式碼中的 context.teamsync.apiBase 與 authHeaders()。憑證由後端產生、只送進 Worker,永遠不顯示。所有 Edge Workers 路由現在都拒絕服務帳號(403 Service accounts cannot invoke Edge Workers)。更新的頁面:服務帳號、管理服務帳號、驗證與角色、端點、Schema。
  • 範本、CLI 壓縮檔與原始碼下載(#1709,v5.13.0;#1790,v5.14.0)。GET /starters、GET /starters/cli.tgz、GET /starters/{starter_id}/{language}/source.zip、GET /starters/{starter_id}/{language}/department-worker.tar.gz,以及 GET /worker/versions/{version_id}/source(部門管理者;原樣回傳儲存的壓縮檔,並以 SHA-256 檢查)。獨立的 teamsync-service Swagger 站已移除(#1714):契約改在網頁 App 的「部門 Worker →『API 文件』」顯示。CLI:init 會寫入 .gitignore、dev 會讀取本機機密並收緊儲存權限、generate 為 secrets 產生型別。更新的頁面:範本與原始碼下載、快速上手、CLI — teamsync-worker、什麼是 Edge Workers。
  • Builder 政策 department-worker-project-v2.5 → v2.9。 v2.6 加入機密讀取,v2.7 加入機密寫入,v2.8 加入操作設定,v2.9 加入服務帳號憑證。需要較新政策的管理路由會回 409,直到專案重新上傳並部署;一旦 v2.8 或更新的 release 在線上,就無法再部署較舊的 release。更新的頁面:提交管線、Manifest 契約、架構與信任邊界、Schema。
  • 刪除部門或公司現在會退役其雲端 Worker(#1727、#1730、#1733、#1734、#1739,v5.13.0;#1813,v5.14.0)。准入先被鎖定(403 worker_retired,適用 v2.8 及更新的 release),機密與服務帳號憑證被清除,接著腳本被覆寫為墓碑,回 404 worker_not_found,並讓 Cloudflare 刪除該 Worker 的 Durable Object 資料;每個 API 副本上的 15 秒調節迴圈會重試直到退役被確認,已刪除部門的部署會被拒絕(department_deleted),因公司硬刪除而遺留的孤兒 Worker 會被清掃,orphan_report 會印出計數。更新的頁面:退役、稽核與控制面稽核、背景任務、環境變數。
  • 共用位置路由(#2143,v5.21.0;維運者)。每個環境的 dispatcher 綁定一個共用的 Worker 位置加上兩個舊位置;除非由伺服器端持有的啟用對照表(EDGE_WORKERS_SERVING_ROUTES,dispatcher 變數 EDGE_WORKER_SERVING_ROUTES)把某個腳本釘在特定位置,否則依固定順序(舊版 staging、舊版 production、共用位置)查找 Worker;被釘定的腳本若在其位置不存在就是 404,絕不改到別處查找。dispatcher 會在 Worker 回應上設定 x-teamsync-serving-namespace 與 x-teamsync-routing-epoch,接受選用的 serving_target 斷言 claim(第 11 個拒絕代碼;已釋出的後端不會送出它),而後端現在依 API 環境而非 namespace 變數選擇 dispatcher。deploy-platform.mjs 會驗證三個 binding 與完整的對照表,且第一次部署 dispatcher 必須提供對照表變數。更新的頁面:架構與信任邊界、調度協定、平台佈建、環境變數。
  • 地端 Edge Workers(#1688,v5.12.0;#1693、#1696、#1699、#1702,v5.13.0;#1972,v5.19.0)。EDGE_WORKERS_PROVIDER=onprem 讓部門 Worker 跑在客戶自己的套件上:一個 edge host,每個 Worker 一個 workerd 行程、前面有 relay,一個專用的產物儲存,以及與雲端相同的專案、builder、API 與 OpenAPI,另有維運指令 resync、backup_fence 與 edge-hostctl,以及 setup-edge-workers-onprem.sh。provider 設定不合法時,提交、部署與修復回 503 Edge Worker provider is not configured。更新的頁面:地端 Edge Workers、架構與信任邊界、限制一覽、環境變數。
  • 同一範圍內較小的變更。 成員 OpenAPI 提供 bearer 與操作金鑰兩種安全機制(#1725);控制通道的拒絕現在以有代碼的內容回應(例如 503 worker_release_unavailable);超過 409 600 位元組的機密 PUT 內容與超過 65 536 位元組的操作設定內容,會在驗證之前以 413 拒絕,機密寫入失敗時的 422 也絕不回顯該值。更新的頁面:錯誤、限制一覽、端點。

早先頁面的更正(這些說法在 5.10.11 時就已不正確,本次修訂已更正):

  • Builder 拒絕。 專案未通過鎖定的建置政策時,任何 builder 拒絕代碼對外一律回 422,type 為 project_invalid;具體代碼只會出現在本機 teamsync-worker validate 的輸出。提交時有代碼的 503 只會是 builder_unavailable 或 builder_invalid_output。
  • 控制通道大小。 後端送出的控制指令最大 1 MiB,但生成的 runtime 最多只接受其中 256 KiB;控制回應上限為 256 KiB。
  • 執行期設定的鍵為 1 到 256 個 UTF-8 位元組,且不得含 NUL(空鍵會被拒絕)。
  • IP 允許清單不會自動去重:正規化之後重複的項目會以 422 拒絕。
  • 票證狀態。 對輪詢票證的用戶端而言,uncertain 不是終止狀態(終止狀態為 completed、failed、cancelled),儘管任務端的 TERMINAL_STATUSES 常數包含它。
  • EdgeWorkerParameterLocation 有三個成員:path、query 與 header。
  • 驗證之前就回 413 只適用於有大小上限的路由(版本提交、執行期設定、機密寫入、存取政策及其金鑰、操作設定、公司修復),而非整個 API。
  • 驗證。 對有效 JWT 的帳號狀態失敗,後端確實會回 401 Account not verified yet,以及 451、409、410;只有缺少或無法解碼的 token 才是 418。x-api-key 這類非 JWT 憑證根本不會被讀取,因此同樣得到 418;模組的 403 Edge Workers require TeamSync JWT authentication 檢查走不到。
  • Manifest 規格。 更正了八處敘述,包括路徑參數樣式的寫法(舊寫法會讓 manifest 被拒絕)、api 物件(鍵為其子集合且有三個必填,而非恰好五個),以及合法的根路徑 /。
  • Builder 映像檔。 以 npm ci --omit=dev 搭配 NPM_CONFIG_IGNORE_SCRIPTS=true 安裝,而不是在命令列加 --ignore-scripts。
  • 刪除部門與公司。 刪除部門是軟刪除(不會連帶刪除任何資料);公司的硬刪除會連帶刪除其 Worker 與版本,outbox 與稽核資料列則保留。

稽核備註 — 已檢視而排除:觸及上述稽核路徑的有 248 個非合併 commit(另有 54 個合併 commit),不計入每個模組共用的 src/server.py(另有 24 個 commit 只動這個檔案,屬於其他模組)。這 248 個之中,6 個只改測試,37 個只動 src/schemas/enums.py 中其他模組的列舉,3 個只動 src/workers/pubsub_consumer.py(其他模組的內建項目;edge 部署項目不變),106 個只動套件其餘部分的地端安裝指南與 PDF(其中兩個同時在 src/schemas/enums.py 為其他模組改了一行;Edge Workers 章節由地端頁面涵蓋),其餘 96 個變更 Edge Workers 的檔案(產品程式碼、edge host、地端安裝腳本與 compose 檔、設計與部署筆記、CI),讀者可見的影響已反映在上文。依設計不記載的內容:開發環境與基礎設施變更(例如 #2018)、CI 與測試套件、edge host 的內部協定、當機矩陣與測試故障注入、Custom Tables 的觸發與排程綁定以及 QA 資料來源設定(呼叫頁面只描述 handler 觀察得到的部分),以及內部 namespace 名稱與專案 id。

2026-09-19 — production v5.10.11:由後端簽發的 500 子請求上限、首次部署預設不公開、以就緒檢查把關的票證

釘選從 f5c893f48 移到 70862ceae7869470c14f4ed7cc7dfc3609e299f4,即 tag v5.10.11(chore: bump version to 5.10.11)— 目前在 production 運行的後端:「Release & Deploy to GCP (production)」工作流程於 2026-09-19 成功結束,production 的 /openapi.json 讀回 info.version = 5.10.11。這個釘選就是 91446e5ee(#1530 的合併)加上只改 VERSION 的版本號 commit;staging 自其 deploy 起就在跑該合併(記錄於 PR #1528–#1530)。依下方路徑稽核(自 f5c893f48 起的 diff + log),找到七個 edge-worker commit(PR #1205 與 #1525–#1530;#1525–#1527 已隨 v5.10.10 上線)。對串接方而言的變更:

  • 每次呼叫的上限現在是 500 個子請求/50 ms CPU,且由後端簽發。 #1205(2026-09-07 合併)把三段 wrangler.jsonc 的 EDGE_WORKER_SUBREQUESTS 從 10 調到 500,但 dispatcher 自 2026-09-03 起就沒再部署,staging 與 production 一直實施 10(issue #1511)。兩個 dispatcher 於 2026-09-19(Asia/Taipei;UTC 為 2026-09-18)重新部署;PR #1525 記錄 production dispatcher f050427f 讀回 EDGE_WORKER_SUBREQUESTS=500、EDGE_WORKER_CPU_MS=50。自 #1525/#1526 起,簽章通道不再依賴這兩個變數:後端依 EDGE_WORKERS_LIMIT_CPU_MS/EDGE_WORKERS_LIMIT_SUBREQUESTS(預設 50/500,範圍 1–30 000/1–1 000;值不合法時後端拒絕簽章,閘道呼叫回 503)加上 limits claim {cpu_ms, subrequests},由 dispatcher 套用。公開通道,以及任何沒帶這個 claim 的斷言,仍使用 dispatcher 變數(50/500)。超過任一上限仍回 429 worker_limit_exceeded。更新的頁面:首頁、什麼是 Edge Workers、架構、限制、調度協定、執行期儲存、呼叫、錯誤、環境變數、平台佈建。
  • 部門的第一次部署起始為 teamsync_internal,不再是 public(#1530)。以 builder 政策 department-worker-project-v2.5 建置的 bundle 會把全新 Worker 的存取政策播種為 teamsync_internal、revision 0,因此在部門管理者 PUT 其他模式之前,公開 URL 一律回 403 access_denied。播種用 INSERT OR IGNORE,已存有政策的 Worker 在後續部署中保留原政策。更新的頁面:首頁、快速開始、存取模式、管理存取政策。
  • 票證 completed 現在代表 release 已能回應(#1530)。Cloudflare 回讀吻合後,部署任務會在 60 秒輪詢截止點下(退避 1 → 5 秒)透過簽章控制通道送出唯讀的 access_policy.get,只有收到回應才結算 completed。截止點是在每次探測後檢查,因此最後一次探測可能在 60 秒後才結束;始終沒有回應的 release 以新的票證 error_code worker_readiness_timeout 進入 uncertain(Worker 暫停;公司修復會跑同一個檢查)。更新的頁面:版本與部署、部署與輪詢、公司管理員、錯誤、限制、背景任務。
  • 閘道改送自己的 User-Agent(#1528)。後端 → dispatcher 的請求現在一律帶 User-Agent: teamsync-backend-edge-gateway,使用函式庫 agent(例如 Python-urllib)的呼叫者不再從 /worker/invoke/… 收到 Cloudflare 不透明的 403 error code: 1010。在這條通道上 handler 看到的是後端的 agent;呼叫者原本的 agent 改放在 x-client-user-agent(≤256 字元,空值時省略,呼叫者自帶的同名 header 會被丟棄)。公開通道不變。更新的頁面:呼叫、調度協定。
  • Builder 政策 department-worker-project-v2.4 → v2.5(#1530,因為 runtime template 產出的程式碼改變)。新建置會得到新的 release generation;先前建置的修訂版保留其記錄的政策,照原樣部署。更新的頁面:架構、提交管線、npm 依賴政策、schema、平台維運總覽。

同一版本中面向維運的變更:outbox 依 dispatch namespace 分區(#1529)— edge_worker_outbox.dispatch_namespace 記錄寫入環境的 EDGE_WORKERS_CLOUDFLARE_DISPATCH_NAMESPACE,四個回收認領掃描只取自己 namespace 與舊版 "" 的列;原因是 production 的調節器先前一直在認領 staging 的控制面稽核(頁面:資料庫模型、背景任務、環境變數)。dispatcher 現在會在後端之前自行部署(#1527)— deploy-platform.mjs 會把 EDGE_DISPATCHER_SOURCE_DIGEST 蓋進每個 dispatcher,並新增 --drift(exit 0 一致/10 漂移或未蓋章/1 失敗);dispatcher 部署工作流程由 staging 部署與 production release 在後端 job 之前呼叫,只在漂移時重新部署,失敗即關閉(頁面:平台佈建、平台維運總覽、測試、環境變數)。

稽核備註 — 沒有已記載的契約改變:bcc635902 與 3256eb15e(承載部署任務的 Pub/Sub consumer 現在會正確處理在 streaming pull 建立前就抵達的 SIGTERM);ebf8c6d6e(為 AI 媒體驗證任務新增兩個內建 self-gated 項目;edge 部署項目不變);4b2b2ba9c(src/server.py:JSON middleware 在 Starlette ≥ 1.0 下不再截斷 StreamingResponse 的 body,閘道呼叫的回應恢復為如文件所述的原樣串流);觸及 src/schemas/enums.py 的其餘 27 個 commit(連同 ebf8c6d6e 共 28 個)只改了非 edge 的列舉(EdgeWorkerLanguage 逐位元組相同)。七個 PR 的合併 commit 本身沒有額外修改。

2026-09-03 — 部門 Worker 的對外連線改為不受限制

部門 Worker 的對外網路存取現在不受限制。全拒的 Outbound Worker 已移除,dispatch namespace 的 binding 在所有環境都不再帶 outbound 鍵,所以部門程式碼的 fetch() 直接送達目的地 — 沒有允許清單、政策、功能旗標或環境變數會攔住對外連線(Cloudflare 同樣不再攔截 connect(),但部門 bundle 仍無法匯入 cloudflare:sockets,因此 fetch() 是唯一的對外原語)。deploy-platform.mjs 現在跑兩個 Wrangler 階段(dispatcher、canary)、拒絕任何綁定 outbound Worker 的 dispatcher 設定、透過 Cloudflare API 一次性退役先前部署的 teamsync-department-worker-outbound-deny-<env> Worker(settings GET → DELETE ?force=true → 讀回不存在;已不存在則跳過),而簽章 canary 改為證明對 https://www.cloudflare.com/cdn-cgi/trace 拿到 200,而非 403 拒絕。每次呼叫的上限(EDGE_WORKER_SUBREQUESTS=10、EDGE_WORKER_CPU_MS=50)維持不變。更新的頁面:什麼是 Edge Workers、架構、限制、執行期儲存、呼叫、平台維運總覽、平台佈建、測試、錯誤、環境變數、CLI。釘選已移到 f5c893f48(#1134 的合併),方法是以下方的稽核 diff 對照前一個釘選 5284e263e 重跑一次:除了兩個 outbound PR,唯一的 edge-worker 後端變更是 263a68fb5,把合成 GET /worker/openapi.json 範例裡的 $ref 改成字面值,讓會展開參照的客戶端不再對根規格懸空 — 沒有任何已記載的契約改變。上線狀態:帶閘門的腳本已於 2026-09-03 部署到 staging 與 production;兩個舊版全拒 Worker(teamsync-department-worker-outbound-deny-staging/-production)都已退役,往後每次部署的退役步驟只剩一次唯讀 GET。同日追加:deploy-platform.mjs 現在以 --no-experimental-provision 執行 Wrangler,並在退役舊版全拒 Worker 之前先從 Cloudflare 讀回已部署 dispatcher 的 settings — Wrangler 的資源佈建曾把既有的 dispatch namespace binding 以 type: "inherit" 上傳、保留舊的 outbound,第一次 staging 部署因此刪掉了 dispatcher 仍在參照的 Worker(所有呼叫回 502,直到修復為止)。--allow-api-overwrite 供手動 API 修復之後的那一次部署使用。

2026-08-24 — 初版手冊

Edge Workers 模組(V2-only 實作,Workers for Platforms)的第一次完整稽核。手冊中的一切 — 路由、schema、列舉、限制、任務狀態機、調度協定、CLI、平台佈建 — 都讀自上方釘選的程式碼樹;設計文件 edge-workers-plan.md 僅用於敘事框架,一切以程式碼為準。

如何更新釘選

git -C ../teamsync-backend fetch origin master git -C ../teamsync-backend log -1 --format='%H %s %ci' origin/master git -C ../teamsync-backend diff 9d7e0c69ad99fe5ff9becd647a07451c6adbf07b..origin/master -- \ src/routers/private/modules/edge_workers \ src/schemas/edge_workers.py src/schemas/edge_worker_company_admin.py src/schemas/edge_worker_secrets.py \ src/schemas/edge_worker_service_accounts.py src/schemas/edge_worker_header_policy.py src/schemas/enums.py \ src/components/edge_workers \ src/crud/edge_workers src/crud/service_accounts.py \ src/database/models/edge_worker.py \ 'src/tasks/edge_worker_*_task.py' \ src/dependencies/edge_workers.py src/dependencies/service_accounts.py \ src/crud/department.py src/crud/company.py src/crud/custom_table_edge_workers.py src/components/qa_department_worker.py \ src/workers/pubsub_consumer.py src/server.py \ edge \ scripts/edge-workers scripts/setup-edge-workers-onprem.sh docker-compose.edge-workers.yaml \ docs/architecture/edge-workers-plan.md docs/deployment \ .github/workflows/edge-dispatcher-deploy.yml .github/workflows/gcp-deploy.yml .github/workflows/release-deploy.yml
Last updated on