コンテンツにスキップ

レビュー証拠とワークフロー下書き

タスクのレビュー画面でスナップショットを取得してから、成果物を受け入れるか下書きを作成します。ハッシュは契約リビジョン、成果物の内容、閲覧対象を固定します。内容が変わっていないことと成果の正しさは別です。従業員の成功報告は自己申告のまま、旧成果物は未確認のままです。ファイルや契約の変更は証拠を古いものにします。受け入れられるのはタスクの最新のスナップショットだけです。画面に古いスナップショットが表示されている間に別の人が新しいものを取得した場合、古い方の受け入れは拒否されます。すべての成果物を含められなかったスナップショットは受け入れられません。スナップショットの取得と受け入れ、テスト実行、審査への提出、適用、取り消しには、その AI 従業員に対する Operator 以上の割り当てが必要です。

完了タスクは DATA ソースとして無効な下書きを作成できます。インストール済みスキル ID、型付きステップと入出力スキーマ、必要なツール、5 種類のケースと期待動作、費用上限、入力期限、タイムゾーンを指定します。サーバーはスキルと現行権限を固定します。保存だけではツールやスケジュールを有効化しません。必要なツールは AI 従業員の現在の許可・禁止ツール一覧とだけ照合するため、上限の見積もりです。権限スイッチ、承認が必要なツール、タスク単位の許可などは照合に含まれず、実行時にはそのまま適用されます。停止条件は下書きの項目から外しました。実行する仕組みがなかったためです。実行を止めるのは下記の費用上限、回数上限、連続失敗の上限です。

正常、空入力、期限切れ、注入、権限不足のケースを試行します。正式な runner と操作記録を使い、staging の許可対象を明示的に制限します。OS による隔離ではありません。実際の実行 ID、状態、ハッシュ、検証結果を確認してください。期待どおりの拒否は検証に一致しても実行状態は blocked のままです。モデルの「成功した」という文章は証拠ではありません。3 種類の否定ケースは名前どおりの状況を含み、そのゲート自身のエラーコードで終わる必要があります。期限切れケースは入力期限より古い observed_at を持ち、workflow_input_expired(または workflow_read_data_expired)で終わります。注入ケースは入力ガードが止める入力で、input_injection_blocked で終わります。権限不足ケースは権限拒否 workflow_read_denied:-32003 または workflow_effect_refused:-32003 で終わります。スキーマエラー、人による拒否、ケースに書き込んだ判断はこの 3 種類の合格になりません。

5 ケースの証拠が有効な間に固定リビジョンを審査に提出します。人の決定は下書き、スキル、ケースのダイジェスト、効果テンプレート、閲覧対象、費用、任意のスケジュールを対象にします。適用時にサービス状態を再取得し、未承認、期限切れ、変更済みの材料を拒否します。有効化後は承認済みリビジョンがそれ自体の根拠になります。元タスクや成果物を後から変更しても実行は止まりません。インストール済みスキルが変わると実行は止まり、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 の削除は準備済みの操作にも適用されます。従業員の所有権、能力、人による承認の検査は引き続き必要です。

タスクの内容を見られるのは誰か

Section titled “タスクの内容を見られるのは誰か”

閲覧対象は運用者が設定するプライバシー機能ではありません。チームのラウンドで AI のロールメンバーが書く受け渡しデータ(team_handoff)に由来し、各データが内容を渡してよい相手を記載できます。一覧にあるロール名(verifier など)はロール間の受け渡しだけを制限し、人は制限しません。人を制限するのは user:<アカウント ID>、role:<ダッシュボードのロール>、channel:<チャンネル> の 3 種類の項目だけです。これらがなければ、タスクは通常のアクセス規則に従います。複数のデータにこの種の項目がある場合は共通する項目だけが残り、共通する項目がなければ管理者だけが見られます。

制限されるもの:管理者でないダッシュボード利用者です。タスクの中身を示すもの(レビュー画面と下書き、成果物とダウンロード、ファイル変更、各ラウンドの結果と判定コメント、タイムライン、コメント、役割ごとの実行、実行記録、このタスクから作られた承認カード、ダッシュボードのリアルタイム更新)はすべて従い、対象外の人は一覧でタスクカード(タイトル、状態、担当の AI 従業員、時刻)だけを見られます。ダッシュボード利用者は user:、role:、channel:dashboard で照合します。一覧が channel:telegram だけなら、管理者以外のダッシュボード利用者は内容を見られません。タスクの内容の読み取りと、タスクに対する変更(状態、決定、割り当て、アーカイブ、ピン留め、名前変更、削除)は、毎回アカウントのロール、状態、割り当てとタスクの一覧を読み直します。そのため割り当ての取り消し、ロールの引き下げ、アカウント停止の後は、開いている接続でもこれらができなくなります。ダッシュボードのリアルタイム更新は 2 秒以内に追いつきます(下の「ダッシュボードのリアルタイム更新」を参照)。その他のダッシュボードのリクエストは従来の確認のままです。

制限できないもの:管理者アカウント(その時点でロールを読み直します)と gateway 管理トークンは常に閲覧と決定ができます。人の対応を待つ非公開タスクも同じです。AI が書いた一覧で管理者の監督を外すことはできません。

タスクが削除された後に残るもの(各ラウンドの実行記録、アクティビティフィードの項目、そこから作られたワークフローの下書きと実行)は、管理者だけが閲覧・操作できます。

チャンネル:channel:X は 1 つのチャットではなくチャットプラットフォーム全体を指します。このゲートウェイにつながっているそのプラットフォームのチャットはすべて一覧に含まれます。チャンネル X は、人への制限がないか、一覧に channel:X があるときに完全な通知を受け取り、ボタンで決定できます。そうでなければ「何かが起きた」こととダッシュボードへのリンクだけを受け取り、ボタンは拒否されます。ロール名だけを書いたタスクは、どのチャンネルでも以前とまったく同じ動作です。

記録:人を制限した最初の受け渡しデータは、タスク、ラウンド、書き込んだロールとアカウント、制限した項目をアクティビティフィードとセキュリティ監査に記録します。管理者のタスク画面には、その制限とどのデータが設定したかが表示されます。受け渡しデータを読めないか破損している場合、管理者以外は閲覧できず、管理者のタスク画面にその旨が表示され、アクティビティフィードに一度記録されます。

非公開ファイルの制限は添付フォルダー内のファイル名に結び付いています。同じファイルの別名(シンボリックリンクやハードリンク)は制限のないファイルとして扱わず拒否します。AI 従業員が自分の成果物を新しいファイルにコピーすることは防げず、これはこの設計の限界です。制限のないファイルはサインイン用トークンの権限で判断するため、割り当ての取り消しはそのトークンの期限切れ後に反映されます。再接続時はタスクのページ付きリストから下書きを再取得します。

ダッシュボードのリアルタイム更新

Section titled “ダッシュボードのリアルタイム更新”

ゲートウェイがダッシュボードのタブに送るリアルタイム更新は、送信前にそのタブのアカウントと照合します。アカウント情報はタブごとに最大 2 秒に 1 回読み直します。

更新 受け取る人
ゲートウェイの状態、更新の有無と進捗、メンテナンスモード すべてのタブ(ロック画面を含む)
ダッシュボードに開くよう求められたページ、削除されたタスクの ID、チャットプラットフォームのキューが満杯になったこと サインイン済みのすべてのアカウント
タスクの作成・変更、タスクのコメント、アクティビティフィードの項目 そのタスクの AI 従業員にアクセスできるアカウント。一覧の対象外の人には、変更はタスクカードだけ、アクティビティは本文なし、コメントは送りません。削除されたタスクの項目は管理者だけに送ります
ある AI 従業員の会話、計画、キャンバス、ルーティン、記憶、スキル、チャンネル設定 その AI 従業員にアクセスできるアカウント
サインインとインストールの出力、チャットの配信失敗、ここにない種類の更新 管理者のみ
ゲートウェイのログストリーム(ログ画面) マネージャーと管理者。現在のロールで再確認します
  • AI 従業員は自分のツール(tasks_list、activity_list、プロンプト内のタスクボード)でタスクを読みます。一覧で制限されたタスクは、そのタスクが属する従業員(担当者、取得者、作成者)と、一覧が role:<従業員 id> で名指しした従業員にだけ表示されます。引き継ぎデータを読めないタスクは、属する従業員にだけ表示されます。オペレーターの MCP 呼び出しは制限されません。それ以外では、一覧が制限するのは人がダッシュボードとチャットで見られる内容です。
  • ログストリームは、ゲートウェイが記録するすべての内容(すべての AI 従業員分)をすべてのマネージャーと管理者に見せます。
  • 最初のアカウントを作る前に開いたダッシュボードのタブは、閉じるまでゲートウェイ管理者の権限を保ちます。

有効化されたワークフローの実行

Section titled “有効化されたワークフローの実行”

有効化されたリビジョンはスケジュールまたはオペレーターの手動トリガーで実行されます。1 回のトリガーにつき実行は 1 つで、同じスケジュール枠や同じ手動 request ID は常に同じ実行に対応します。

承認ステップと質問ステップ。 承認ステップ、質問ステップ、ポリシーで ask とした書き込み操作に達すると実行は止まり、カードが受信箱に出ます。ダッシュボードでステップのカードを決定できるのは、現在のロールがマネージャーまたは管理者で、その AI 従業員にアクセスでき、実行の閲覧対象に含まれる人だけです。それ以外の人はカードを見られますが、バインド情報は表示されず、決定もできません。ステップのカードはダッシュボードでのみ決定します。決定できる人には、確認済みのチャットに内容を含まない通知が届きます(下の「通知を受け取る人」を参照)。そこで返信しても何も決定されません。決定すると同じ実行が同じトランザクション内で再びキューに入り(その間にゲートウェイが止まった場合は、バックグラウンドの巡回が約 1 分以内に不足したキュー項目を補います)、完了済みのステップは繰り返されません。承認されたステップは先に進みますが、実行は何かを行う前にポリシー、閲覧対象、権限付与、入力の鮮度を再確認します。拒否されたカードは実行を failed/workflow_approval_denied で終わらせます。誰も決めないカードは実行の待機期間(24 時間、または権限付与の期限の早い方)とともに期限切れになり、巡回が約 1 分以内に検知して実行を failed/workflow_approval_expired で終わらせます。実行自体の期限が同時に来た場合も同じです。カードの待機中に AI 従業員の権限が変わると、カードは決定できなくなり、実行は待機期間の終わりまで待ちます。各ステップで決定できるカードは最大 1 枚です。

鮮度は実際に読み取った時刻で判断します。実行入力の鮮度(input_max_age_seconds)は開始時と、入力が実行入力に由来する書き込み操作の直前に確認します。前のステップで読んだデータも、書き込み操作が使う時点で同じだけ新しい必要があります。入力が定義に固定されている書き込み操作(リテラル、承認ステップ経由を含む)は入力の鮮度に縛られないため、人が何時間もかけて承認しても失敗しません。データが古くなって止まった実行は workflow_input_expired または workflow_read_data_expired(失敗区分 stale)で止まり、連続失敗の上限には数えません。

データディレクトリごとにゲートウェイは 1 つ。 ゲートウェイは起動時に <home>/locks/gateway.lock を取得し、動いている間保持します。中断された実行の引き継ぎ、キューに入ったワークフローの送出、バックグラウンドの巡回は保持者だけが行います。同じデータディレクトリで起動した 2 つ目のゲートウェイはエラーを記録し、ワークフローには触れません。duduclaw doctor の「単一 gateway」行に保持者が表示され、拒否されたゲートウェイがあると警告します。保持者の pid=… since=… 行はサイドカー <home>/locks/gateway.lock.holder に書かれます(ロックファイル自体は空のままです。Windows ではロック中のファイルを他のプロセスが読めないためです)。

再起動とクラッシュ。 ゲートウェイを再起動すると、古いプロセスが実行していた実行を解放して続けます。完了済みのステップは繰り返されません。書き込み操作の最中にプロセスが止まった場合、実行は uncertain/effect_outcome_unconfirmed で終わり、その操作が実行に表示されます。書き込み操作は再送されません。管理者が操作一覧から処理します。基盤エラー(データベースのビジー、ツールプロセスの起動失敗、別プロセスが操作を保持中、設定が一時的に読めない)は数回再試行し、書き込み操作の拒否としては扱いません。失敗が続くと実行は workflow_transient_retry_exhausted で止まり、これは連続失敗の上限に数えません。実行ファイルを更新すると環境のフィンガープリントが変わるため、更新をまたいで待機していた実行は続行せず止まります。

停止。 workflow_runs.cancel(その AI 従業員にオペレーターのバインドを持つマネージャー)は 1 つの実行を止めます。次のステップは始まらず、未決定のカードは取り下げられ、まだ始まっていない書き込み操作は始められなくなります。すでに始まった書き込み操作は元に戻らず、そのステップに表示されたままになります。有効化を取り消すと、以後のすべての実行が止まります。

連続失敗。 失敗、停止、結果不明の実行が max_consecutive_failures 回続くと、新しい実行は workflow_consecutive_failure_limit で拒否されます。管理者は workflow_runs.reset_failures(理由は必須)で再有効化せずに回数をリセットでき、それ以前の実行は数えなくなります。取消された実行、基盤エラーの再試行切れ、上限による停止、データの期限切れによる停止は数えません。

スケジュール。 ルーティンを有効化または再有効化すると、その時点から始まります。無効だった間の枠は後から実行されません。停止期間の後は、直近 24 時間以内に逃した最後の枠を 1 回だけ実行します。それより古い枠は諦め、ルーティンに記録します(last_status = skipped、件数付き)。時刻はルーティンのタイムゾーンに従います。夏時間のあるタイムゾーンでは、2 回現れる現地時刻は 2 回実行し、飛ばされる現地時刻は実行しません。台湾には夏時間がありません。

workflow_runs.get と workflow_runs.list は、各実行の状態、エラーコード、失敗区分、各ステップの状態(決定カードと操作の状態を含む)を返します。

ワークフローのバージョン承認は、管理者がダッシュボードでのみ行います。チャットにボタンは付かず、チャットでの返信では決まりません。管理者への通知は、有効化の審査待ちがあることと期限だけを伝えます。カードには有効化の終了日も表示されます(「有効化の期限」を参照)。決定時点のロールを読み直します。管理者は自分が提出した申請を承認できますが、カードと監査記録(workflow_activation_decided)に申請者と承認者が同一であることが残ります。

各書き込み操作が変更できるのは 1 つのレコードだけで、有効化の時点で固定されます。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 # 1 実行あたりのステップ送出数(再試行を含む)
max_reads_per_run = 20 # 1 実行あたりの読み取り試行数
max_effects_per_run = 10 # 1 実行あたりの書き込みステップ数

下書きの実行単位・月単位の費用上限はマイクロ単位で、オペレーターが設定した単価で計上します。

[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 を返し、効くのは回数の上限だけです。サーバーはステップの「実行中」チェックポイントと同じトランザクションで、ステップが動く前に計上します。読み取りは試行ごと、承認ステップと書き込みステップは 1 回ずつです。読めない単価は不明として上限で計上します(その実行の残り予算を使い切ります)。台帳に計上のない書き込み操作は取得できません。予算や回数に達すると実行は blocked(失敗区分 limit、例:workflow_budget_exhausted、workflow_limit_reads_per_run)で終わり、連続失敗の上限には数えません。[workflow.limits] に無効な値があると、修正するまですべての実行が拒否されます。

回数は定義そのものとも照合します。1 回の実行で使える数より多いステップ・読み取り・書き込みを持つ定義、または現在の単価で最も安い 1 回が実行単位の予算を超える定義は有効化できません。後から上限を下げて有効化済みの定義が収まらなくなると、次のトリガーは拒否され、有効化は理由 limit で一時停止します。max_consecutive_failures 回連続で上限により終わった場合も同じです。どちらも管理者に通知します。

有効化は、管理者が承認した時点の AI 従業員の権限を記憶します。実効の [capabilities]、[permissions]、[agent] の上長・部署・ロール(職務プリセットの解決結果を含む)、CONTRACT.toml、プリセットの割り当て、org.toml の本人と上長のレコード、config.toml の [delegation]・[acp]・[provenance]・[integrations]、KILLSWITCH.toml です。その他の設定(チャネルのトークン、他のスケジュール、常駐センシングのソース、ログレベル)は影響しません。実行がこの権限の変化を見つけると、有効化は suspended になります。その実行は workflow_policy_changed で止まり、新しい実行は始まらず、スケジュールはオフになり、アクティビティフィードと管理者への通知が変わったカテゴリを示し、workflow_runs.get/workflow_drafts.get で理由を確認できます。設定が読めないときはまず数回再試行し、それでも読めない場合にだけ一時停止します。設定の変化を見つけたときも読み直して確認するため、保存途中のファイルで一時停止することはありません。[redaction] とカスタムの匿名化ルールの変更も対象です。

一時停止した有効化は、どの経路でも二度と実行されません。再適用はできず、記録を有効に戻すこともできず、承認台帳の権限付与も取り消され、設定を元に戻しても解除されません。続けるには、タスクから新しい下書きリビジョンを作成し(現在の権限が記録されます)、ケースを再実行して、改めて有効化を申請してください。

テスト実行が証明するのは、受け入れ時点の下書きです。管理者が承認するとき、すべてのケースが有効期限内である必要があります。承認後、有効化は config.toml [workflow] activation_days 日間有効です(既定 30、1〜365。それ以外の値では修正するまで新しい有効化申請が拒否されます)。承認カードと下書きページに終了日が表示されます。ケースの有効期限で短くなることはありません。実行のたびにスキル、AI 従業員の権限、実行環境、閲覧対象、権限付与を確認し直すためです。

終了の 3 日前に管理者へ一度通知します。終了時に有効化は expired になり、スケジュールはオフになり、新しい実行の開始も継続もされず、アクティビティフィードに記録して管理者に通知します。延長はありません。続けるには、新しい下書きリビジョンを作成し、ケースを再実行して、改めて有効化を申請してください。

通知にワークフローの内容は含まれません。何かが待っているか変わったこと、どの AI 従業員か、期限だけを、確認済みのチャットにのみ送ります。

イベント 受信者
有効化申請の審査待ち 有効な管理者アカウント
有効化の一時停止・期限切れ、または期限の 3 日前 有効な管理者アカウント
ステップのカード(承認・質問)待ち 決定できる人:その 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 が必要で、同じリクエストを再送すると同じ実行につながり、もう 1 つ始まることはありません。ダッシュボードの cron.run_now は request_id を付けて呼び出し、run_id と現在の状態を返します。MCP ツール run_cron_task など request ID を渡せない経路は、このスケジュールでは拒否されます。