AIエージェントへWeb運用を任せる場合、監視から本番反映までを一つの資格・一つの処理にまとめないことが出発点です。監視、提案、ローカル生成、承認、反映、独立verifyを分け、工程間では自由文ではなく構造化した記録を渡します。
OpenAI公式では、sandbox modeはコマンドが技術的に触れられる範囲、approval policyは実行前に承認を求める条件として説明されています。ただし、これらはWordPress側の権限、バックアップ、重複更新防止の代わりではありません。
| 工程 | 入力schema | 出力schema | 主体・資格 | 合格条件 |
|---|---|---|---|---|
| 監視 | site_id, url, last_result_id | baseline_id, http, post_version, log_cursor | 監視処理・読取資格 | 対象ID一致、取得項目欠落なし |
| 提案 | baseline_id, request | proposal_id, target, reason, risk | 提案エージェント・本番資格なし | 対象と変更理由が一意 |
| ローカル生成 | proposal_id, baseline_checksum | payload_id, body, checksum | 作成エージェント・workspaceのみ | schema検証、旧checksum保持 |
| 承認 | payload_id, diff, risk, backup_id | approval_id, approver, expires_at | 責任者・承認権限のみ | payload checksumと期限を固定 |
| 反映 | change_id, payload_id, approval_id | result_id, state, remote_version | 限定wrapper・書込資格 | guard全一致、対象1件だけ変更 |
| 独立verify | result_id, expected | verification_id, checks, verdict | 別処理・読取資格 | HTTP、DB、ログが全合格 |
読取資格には投稿更新権限を与えず、書込資格は限定wrapperの実行時だけ供給します。提案・生成工程は本番へ到達できない環境で行います。verifyは反映処理の終了コードを再利用せず、別の観測から判定します。
以下は架空の投稿ID 120 の本文だけを更新する例です。認証値や実在URLは含みません。
change_id: CHG-WP-20260825-001
target:
site_id: site-example
post_id: 120
baseline:
fetched_at: 2026-08-25T09:00:00+09:00
status: publish
modified_gmt: 2026-08-24T01:20:00
content_checksum: sha256:OLD_EXAMPLE
payload:
payload_id: PAYLOAD-001
allowed_fields: [content]
content_file: post-120-content.html
checksum: sha256:NEW_EXAMPLE
backup:
backup_id: BACKUP-001
includes: [post_120_record, rendered_html]
approval:
approval_id: APPROVAL-001
payload_checksum: sha256:NEW_EXAMPLE
expires_at: 2026-08-25T10:00:00+09:00
expected:
post_id: 120
status: publish
content_checksum: sha256:NEW_EXAMPLE
http_status: 200
new_error_count: 0
WordPress REST APIの投稿更新endpointは投稿IDを含み、contentなどのfieldを更新できます。だからこそwrapperでは、任意endpointや任意fieldを受け付けず、post_id=120 と allowed_fields=[content] を固定します。
wrapperは書込み前に次を順番に確認します。
change_id が未実行であるmodified_gmt がbaselineと一致するOLD_EXAMPLE と一致するcontent だけである一つでも不一致ならHTTP更新を呼び出しません。成功時はremote version、更新時刻、応答IDをresultへ保存します。wrapperの代表的な結果は次のようにし、秘密値や本文そのものを監査ログへ複製しません。
{"change_id":"CHG-WP-20260825-001","state":"applied","post_id":120,"result_id":"RESULT-001","remote_version":"2026-08-25T00:05:00Z"}
これはschema例であり、実測結果ではありません。
反映後は、読取資格でREST APIからpost ID、status、modified日時、content checksumを取得します。次に公開URLを未認証のHTTP GETで取得し、status 200、期待する識別文字列、canonicalを確認します。最後にbaselineのlog cursor以降を調べ、新規のPHP fatal、DB error、権限エラーがないことを確認します。
| 確認面 | 合格 | 不合格時 |
|---|---|---|
| DB/API | post ID・status・checksum一致 | 公開成功とせずrollback判断 |
| HTTP | 200かつ期待内容を表示 | cacheとoriginを分けて調査 |
| ログ | 対象時刻以降の新規重大errorなし | 追加変更を止め影響範囲確認 |
HTTPだけ合格してDBが不一致なら、cacheが旧表示を返している可能性があります。DBだけ合格してHTTPが不合格なら、公開経路やcache purgeを確認します。どちらも「もう一度同じpayloadを送る」理由にはなりません。
| 変更 | 自動停止の理由 | 人へ戻す条件 |
|---|---|---|
| 利用規約・免責等の法務文面 | 法的意味の判断が必要 | 法務担当が確定稿と適用日を承認 |
| 料金・割引・税表示 | 契約・請求へ影響 | 事業責任者が金額と期間を承認 |
| 個人情報を含む本文・media | 公開範囲と本人権利へ影響 | 情報管理担当がデータと公開範囲を確認 |
| 決済設定 | 金銭と外部serviceへ副作用 | 決済担当がsandbox testと本番手順を承認 |
| 公開範囲・会員権限 | 閲覧者が変わる | ownerが対象roleとrollbackを承認 |
内容に該当語があるだけで自動修正せず、分類できない場合も停止します。
change_id は not_started、in_progress、succeeded、unknown、rolled_back を区別します。送信前に in_progress を記録し、応答を保存できれば succeeded にします。送信後に通信が切れた場合は unknown とし、再送しません。
unknown では読取資格でremote versionとchecksumを調べます。新checksumならresultを復元して succeeded、旧checksumなら新しい承認の下で再実行、どちらでもなければ影響調査へ移します。rollback後も元のchange IDを再利用せず、新しい作業票を作ります。
baseline、payload checksum、backup ID、approval ID、wrapper version、状態遷移、remote version、verify結果をchange IDへ結びます。資格の識別子は残しても、tokenやcookieは保存しません。
WordPress公式は、アクセス制限、権限の抑制、backup、logging、monitoringを多層で扱っています。AIエージェントの導入を理由に、法務確認、復元試験、利用規約の確認を省略してはいけません。