跳到內容

審查證據與工作流程草稿

開啟任務的「審查證據與工作流程草稿」,先擷取快照,再接受交付物或建立草稿。快照雜湊固定任務約定版本、產物內容與可見對象。內容未變只能證明位元未變;員工的成功摘要仍是自報。舊產物維持未核實,檔案修改、刪除或任務約定變更會讓快照標為過期。只有任務最新的一份快照可以接受:畫面還停在舊快照時若有人擷取了新的,接受舊的會被拒絕。沒收齊所有產物的快照不能接受。擷取與接受快照、試跑、送審、套用、撤銷,都需要對該 AI 員工有 Operator 以上的綁定。

已完成任務可提供 DATA 來源,建立停用草稿。提案需提供已安裝技能 ID、輸入/輸出結構、型別化步驟、需要的工具、五類案例輸入與預期行為、費用上限、有效期限與時區。服務端固定技能、來源快照與建立者現行權限;儲存不會授權工具或啟用排程。草稿需要的工具只和 AI 員工目前允許與禁止的工具清單比對,所以是上限估計:權限開關、需要核准的工具、任務授權等其他關卡不在比對內,正式執行時仍然有效。草稿已不再填停止條件,因為沒有任何地方執行它;執行會停下來靠的是下文的費用上限、次數上限與連續失敗上限。

分別試跑正常、空輸入、過期、注入與缺少權限案例。所有試跑走正式 runner 與操作紀錄;staging 資源需由操作者明確允許,這並非作業系統隔離。畫面顯示實際執行 ID、狀態、結果雜湊與斷言結果。預期拒絕可以符合斷言,實際執行仍保持 blocked;模型自行宣稱通過不算證據。三類負面案例必須真的帶著它的名稱所指的情況,並以該關卡自己的錯誤碼結束:過期案例的 observed_at 要早於有效期限,結果是 workflow_input_expired(或 workflow_read_data_expired);注入案例的輸入要真的被輸入防護擋下,結果是 input_injection_blocked;缺少權限案例的結果是權限拒絕 workflow_read_denied:-32003 或 workflow_effect_refused:-32003。格式錯誤、被人拒絕,或案例自帶的人工決定,都不算這三類通過。

五類案例都有現行且符合預期的證據後,再送審。人工決策固定草稿、技能、案例摘要、效果範本、可見對象、費用上限與選用排程。套用時重讀真實服務狀態,未核准、過期或資料已變更都會拒絕。案例到期需重新試跑。啟用後,已核准的版本自成依據:之後再修改來源任務或產物不會讓執行停下;已安裝的技能變了會停止執行;AI 員工的權限設定變了會讓啟用進入「暫停」(見下文)。

有寫入操作的試跑,需由操作者在 config.toml 明列測試資源 ID:

[workflow]
fixture_environment = "staging"
allowed_origins = ["https://staging.example.com"]
fixture_task_ids = ["test-task-id"]
fixture_cron_ids = ["test-cron-id"]

只登記可供試跑的測試資料。tasks_update 必須指定清單內的 task_id;update_cron_task 必須指定清單內的 id,不接受依名稱選取。缺少清單、格式錯誤或空清單都不放行。準備操作及真正執行前,會重新檢查工具參數與目前清單,因此移除 ID 也會擋下已準備的操作。員工原有的資料擁有權、能力限制與人工核准仍須通過。

可見名單不是操作者設定的隱私功能。它來自團隊回合裡 AI 角色成員寫的交接資料(team_handoff):每份交接資料可以寫明內容能交給誰。名單裡的角色名稱(例如 verifier)只限制角色之間的傳遞,不限制人。只有 user:<帳號 ID>、role:<儀表板角色>、channel:<通道> 這三種開頭的項目會限制人;交接資料裡沒有這三種項目時,任務照一般的存取規則。多份交接資料都寫了這類項目時,只留下它們共有的;沒有共有的,就只有管理者看得到。

它限制得到的:不是管理者的儀表板使用者。凡是顯示任務做了什麼的地方都照它(審查面板與草稿、產物與下載、檔案變更、各輪結果與判官回饋、時間軸、留言、角色回合、執行紀錄、由任務產生的核准卡片、儀表板即時更新);名單外的人在列表只看得到任務卡(標題、狀態、負責的 AI 員工、時間)。儀表板使用者以 user:、role: 或 channel:dashboard 比對;名單只有 channel:telegram 時,所有非管理者的儀表板使用者都看不到內容。讀取任務內容,以及作用在任務上的變更(狀態、決定、指派、封存、釘選、改名、刪除),每次都重新讀取帳號的角色、狀態、綁定與任務的名單,所以撤銷綁定、調降角色或停用帳號後,開著的連線也立刻做不到這些事;儀表板即時更新在 2 秒內跟上(見下方「儀表板即時更新」)。其他儀表板請求維持原本的檢查。

它限制不到的:管理者帳號(當下重讀角色)與 gateway 管理權杖一律看得到、也能決定,包括等人處理的私有任務。AI 寫的名單不能拿走管理者的監督。

任務被刪除後,留下來的東西(各輪執行紀錄、動態牆紀錄、從它產生的工作流程草稿與執行)只有管理者能讀取與處理。

通道:channel:X 指的是整個聊天平台,不是單一聊天室:這個閘道連著的該平台上每個聊天室都算在名單內。通道 X 在任務沒有對人的限制,或名單含有 channel:X 時,收到完整通知、可以用按鈕決定;否則只收到「有事發生」與儀表板連結,按按鈕會被拒絕。交接資料只寫了角色名稱的任務,在各通道上的行為與以前完全相同。

紀錄:第一份限制到人的交接資料會寫一筆動態牆紀錄與安全稽核,記下任務、第幾輪、寫入的角色與帳號、限制成哪些項目。管理者在任務頁看得到這個限制與是哪一份交接資料設的。交接資料讀不到或損壞時,管理者以外的人一律看不到,任務頁會對管理者標明,動態牆記錄一次。

私有檔案的限制綁在附件資料夾裡的檔名上。同一個檔案的第二個名字(符號連結或硬連結)會被拒絕,不會被當成沒有限制的檔案;AI 員工仍可以把自己產出的內容複製成新檔,這是這個設計本身的限制。沒有綁定限制的檔案依登入憑證判斷,所以撤銷綁定要等那張憑證到期才對它生效。重新連線後可透過任務頁分頁清單重讀草稿。

閘道送給儀表板分頁的每一則即時更新,送出前都會對照該分頁的帳號檢查;帳號資料每個分頁最多每 2 秒重讀一次。

更新 誰會收到
閘道狀態、可用更新與更新進度、維護模式 每個分頁,包括鎖定畫面
要求儀表板開啟的頁面、被刪除任務的 ID、某個聊天平台佇列已滿 每個已登入的帳號
任務建立或變更、任務留言、動態牆紀錄 可存取該任務 AI 員工的帳號;名單外的人收到的變更只有任務卡、動態牆紀錄沒有文字、留言完全不送;已刪除任務的紀錄只送給管理者
某位 AI 員工的對話、計畫、畫布、排程、記憶、技能與通道設定 可存取該 AI 員工的帳號
登入與安裝輸出、聊天送達失敗,以及上面沒列出的任何更新 只有管理者
閘道日誌串流(日誌頁) 經理與管理員,依目前角色重新檢查
  • AI 員工透過自己的工具(tasks_list、activity_list、提示裡的任務板)讀任務。被名單限制的任務,只會出現在它所屬的員工(負責人、認領者、建立者)與名單以 role:<員工 id> 點名的員工那裡;交接資料無法讀取的任務只給所屬員工。操作者的 MCP 呼叫不受限。除此之外,名單限制的是人在儀表板與聊天裡看得到什麼。
  • 日誌串流會把閘道記錄的所有內容(跨所有 AI 員工)給每一位經理與管理員看。
  • 在建立第一個帳號之前開啟的儀表板分頁,在關閉前都保有閘道管理者的權限。

已啟用的版本依排程執行,或由操作者手動觸發。每次觸發只建立一個執行;同一個排程時段或同一個手動 request ID 永遠對應同一個執行。

核准與提問步驟。 執行遇到核准步驟、提問步驟,或政策設為 ask 的寫入操作時會停下,卡片出現在收件匣。在儀表板決定步驟卡片,需要目前角色為經理或管理員、可存取該 AI 員工,而且在該執行的可見對象內;其他人看得到卡片,但看不到綁定細節,也不能決定。步驟卡片只能在儀表板決定;能決定的人會在已驗證的聊天收到一則不含內容的通知(見下方「誰會收到通知」),在那裡回覆不會決定任何事。決定卡片後,同一個執行會在同一筆交易裡重新排入佇列(兩者之間閘道若停止,背景巡檢約一分鐘內會補上缺的佇列項目),已完成的步驟不會重跑。核准讓步驟繼續,但執行在動手前仍會重新檢查政策、可見對象、授權與輸入時效。被拒絕的卡片讓執行以 failed/workflow_approval_denied 結束。沒人決定的卡片隨執行的等待期到期(24 小時,或授權到期時間,以較早者為準);背景巡檢約一分鐘內發現,讓執行以 failed/workflow_approval_expired 結束,執行本身的期限同時到了也一樣。卡片等待期間 AI 員工的權限若有變動,卡片就無法決定,執行會等到等待期結束。每個步驟最多只有一張可決定的卡片。

資料時效看的是實際讀取的時間。執行輸入的時效(input_max_age_seconds)在開始時檢查,並在每個輸入來自執行輸入的寫入操作之前再檢查一次;前面步驟讀到的資料,被寫入操作使用時也要一樣新。輸入寫死在定義裡的寫入操作(字面值,可經過核准步驟)不受輸入時效限制,所以人花好幾小時才核准也不會讓它失敗。因資料過期而停下的執行以 workflow_input_expired 或 workflow_read_data_expired 擋下(失敗類別 stale),不計入連續失敗上限。

一個資料目錄只跑一個閘道。 閘道啟動時取得 <home>/locks/gateway.lock,執行期間一直持有。只有持有者會接續中斷的執行、派送排隊的工作流程,並跑背景巡檢;同一資料目錄上啟動的第二個閘道會記錄錯誤,不碰工作流程。duduclaw doctor 的「單一 gateway」列會顯示持有者,有閘道被拒時會警告。持有者的 pid=… since=… 這行寫在旁檔 <home>/locks/gateway.lock.holder(鎖檔本身保持空白,因為 Windows 上其他行程讀不到被鎖住的檔案)。

重啟與當機。 閘道重啟會釋出舊程序正在跑的執行並接續下去,已完成的步驟不會重做。程序停止時若有寫入操作正在進行,執行以 uncertain/effect_outcome_unconfirmed 結束,該操作顯示在執行上,不會重送;由管理員在操作清單處理。基礎設施錯誤(資料庫忙碌、工具程序沒啟動、另一個程序還占著這個操作、設定一時讀不到)會重試幾次,不會被當成寫入操作被拒絕;一直失敗時執行以 workflow_transient_retry_exhausted 擋下,這種擋下不計入連續失敗上限。升級執行檔會改變環境指紋,所以跨升級還在等待的執行會被擋下,不會接續。

停止。 workflow_runs.cancel(對該 AI 員工有操作者綁定的經理)停止一個執行:下一步不會開始,待決定的卡片會撤回,還沒開始的寫入操作不能再開始。已開始的寫入操作不會復原,會留在該步驟上顯示。撤銷啟用會停止之後所有的執行。

連續失敗。 連續 max_consecutive_failures 次執行失敗、被擋下或結果不確定後,新的執行以 workflow_consecutive_failure_limit 拒絕。管理員可以用 workflow_runs.reset_failures(必須填原因)清除計數,不必重新啟用;之前的執行不再計入。取消的執行、基礎設施重試用盡、上限擋下與資料過期擋下都不計入。

排程。 啟用或重新啟用一個排程時,從那一刻開始算;停用期間的時段不會補跑。停機之後,排程只補跑最近 24 小時內錯過的最後一個時段;更早的時段放棄,並記在排程上(last_status = skipped,附次數)。時間依排程的時區計算:在有日光節約時間的時區,出現兩次的當地時間會跑兩次,被跳過的當地時間不會跑。台灣沒有日光節約時間。

workflow_runs.get 與 workflow_runs.list 回傳每個執行的狀態、錯誤碼、失敗類別,以及每個步驟的狀態,包括它的決定卡片與操作狀態。

接受工作流程版本只能由管理員在儀表板決定。卡片不會在聊天通道附按鈕,通道回覆也無法決定;送給管理員的通知只說有一筆啟用待審與期限。卡片也會顯示啟用到期日(見「啟用期限」)。決定當下會重新讀取決定者的角色。管理員可以核准自己送出的申請,卡片與稽核紀錄(workflow_activation_decided)會標明送審者與核准者是同一人。

每個寫入操作都只能改動一筆資料,而且在啟用時就固定。tasks_update 以 task_id 固定,update_cron_task 以 id 固定(不接受依 name 選取)。效果範本的 resource_scope 必須寫明那個 id,步驟輸入也必須由定義本身產生同一個 id:字面值,或經過 identity、產物、核准步驟原樣傳遞。來自讀取結果、執行輸入或轉換的 id 無法啟用;沒有固定對象的工具不能當作寫入操作。啟用卡片會逐一列出每個寫入操作與它的對象。

上限:次數一律生效,金額要設單價才生效

Section titled “上限:次數一律生效,金額要設單價才生效”

次數上限一律生效,寫在 config.toml:

[workflow.limits]
max_runs_per_month = 500 # 每個工作流程每個 UTC 月份的正式執行數
max_steps_per_run = 128 # 每次執行的步驟派送數(含重試)
max_reads_per_run = 20 # 每次執行的讀取次數
max_effects_per_run = 10 # 每次執行的寫入步驟數

草稿的單次與每月費用上限以微單位計,按操作者設定的單價扣:

[workflow.unit_cost_micros]
read = 0
effect = 0
process = 0
artifact = 0
approval = 0

單價是你對每一步的估價,不是 API 帳單,也不是量到的 CPU 時間。單價預設都是 0;只要全部是 0,金額上限就擋不住任何東西,workflow_runs.get 會回報 pricing.money_limits_effective = false,這時真正生效的只有次數上限。伺服器在步驟寫入「執行中」檢查點的同一筆交易裡記帳,步驟開始做事之前就扣:每次讀取嘗試都扣,核准步驟與寫入步驟各扣一次。讀不出來的單價視為未知,按上限扣(用掉該次執行剩下的額度)。帳本沒有這筆扣款的寫入操作無法被認領。用完額度或次數時,執行以 blocked 結束(失敗類別 limit,例如 workflow_budget_exhausted、workflow_limit_reads_per_run),這類執行不計入連續失敗上限。[workflow.limits] 有無效的值時,所有執行都會被拒絕,直到修正。

次數也會拿定義本身來比。步驟、讀取或寫入多於一次執行可用的上限,或以目前單價計算最便宜的一輪就超過單次額度的定義,無法啟用。之後若把上限調低到已啟用的定義放不下,下一次觸發會被拒絕,啟用以原因 limit 暫停;連續 max_consecutive_failures 次執行都因上限結束時也一樣。兩種情況都會通知管理員。

啟用時會記住管理員核准當下 AI 員工的權限:實際生效的 [capabilities]、[permissions],[agent] 的上級/部門/角色(含職務範本解析結果)、CONTRACT.toml、職務範本綁定、org.toml 中該員工及其上級的紀錄、config.toml 的 [delegation]、[acp]、[provenance]、[integrations],以及 KILLSWITCH.toml。其他設定(通道 token、別的排程、即時監控來源、記錄等級)不影響。執行發現這些權限變了,啟用就會進入 suspended:當次執行以 workflow_policy_changed 擋下、不再開始新執行、排程關閉,動態牆與管理員通知會列出變動的類別,workflow_runs.get/workflow_drafts.get 也看得到原因。設定讀不到時會先重試幾次,重試後仍讀不到才暫停;看到設定變了也會再讀一次確認,所以存檔存到一半的檔案不會造成暫停。[redaction] 與自訂去識別化規則的變動也算在內。

暫停後的啟用不會再以任何方式執行:無法再次套用、紀錄無法改回啟用中、核准紀錄裡的授權一併撤銷,把設定改回去也不會恢復。要繼續,請從任務建立新的草稿版本(它會記下現在的權限),重跑案例,再送一次啟用。

試跑證明的是草稿在被接受當下的狀態:管理員核准時,每個案例都必須還在有效期內。核准後,啟用有效 config.toml [workflow] activation_days 天(預設 30,可設 1 到 365;其他值會讓新的啟用申請被拒絕,直到修正)。核准卡片與草稿頁會顯示到期日。案例的有效期不會縮短它,因為每次執行都會重新檢查技能、AI 員工的權限、執行環境、可見對象與授權。

到期前三天會通知管理員一次。到期時啟用變成 expired:排程關閉,不再開始或接續執行,動態牆留一筆紀錄並通知管理員。沒有延長;要繼續,請建立新的草稿版本、重跑案例,再送一次啟用。

通知一律不含工作流程內容,只說有事待處理或有變動、是哪位 AI 員工、期限到何時,而且只送到已驗證的聊天。

事件 收件人
啟用申請待審 啟用中的管理員帳號
啟用暫停、到期,或到期前三天 啟用中的管理員帳號
步驟卡片(核准或提問)待處理 能決定的人:對該 AI 員工有操作權限、且在執行可見對象內的經理或管理員

沒有人把聊天綁到帳號的部署,這些事只會出現在儀表板收件匣與動態牆。

寫入操作在等人決定之前就已扣款,被拒絕或逾期都不退。處理或產物步驟在當機後重進會再扣一次。單價全為 0 時只會用掉次數。

案例可以依步驟 id 預先寫好人工決定:

"decisions": {
"confirm": {"decision": "approve"},
"update": {"decision": "deny"},
"pick": {"decision": "answer", "text": "B"}
}

approve 與 deny 用在核准步驟與政策設為 ask 的寫入操作;answer 用在提問步驟。試跑直接記錄這些決定(決定者記為 fixture:<執行 id>),不建立收件匣卡片,也不送到任何通道。沒有寫好決定的步驟以 fixture_decision_missing 失敗。用 deny 可以驗證「人拒絕了」的路徑(workflow_approval_denied)。預寫決定只對試跑有效,正式執行一律等真人決定。

已啟用的排程要手動執行,必須帶 request ID,重送同一個請求會接回同一個執行,不會再開一次:儀表板的 cron.run_now 要帶 request_id,回傳 run_id 與目前狀態。MCP 工具 run_cron_task 等無法提供 request ID 的路徑,對這類排程一律拒絕。