本文へ移動
cccskills
無料GitHub で公開日本語紹介

operator-approval-loop

顧客や取引先への返信案を人の承認に結び付け、承認された本文と送信先、送信結果を記録します。修正前の古い承認による送信や、複数の担当処理による重複送信を防ぐ設計です。

原文原文の説明を見る

Operator approval contract with internal filing notices for agent-drafted outbound messages, hashed drafts, epoch-keyed decisions, durable delivery claims and receipts, and a pre-draft baseline gate. Use when an agent drafts messages to external counterparties and a human operator must approve, reject, or steer each send before it leaves.

インストール方法を見る

こんなときに便利

  • 顧客への返信を承認制にしたいとき
  • 承認本文と送信結果を記録したいとき
  • 修正前の承認による送信を防ぎたいとき
  • 下書き前に既存の契約情報を確認したいとき

日本語での紹介

できること

エージェントが作った対外メッセージの下書きを、人の承認を経て送信するための手順と記録方式を定めます。本文のハッシュ値、つまり内容を識別する値と更新時点を承認に結び付け、修正前の承認が新しい本文に使われるのを防ぎます。送信の担当処理を一つに限定する仕組みと、承認者、送信先、送信結果を残す台帳の参考実装も含みます。

こんなときに便利

顧客、仕入先、投資家、パートナーへの返信をエージェントに下書きさせ、人が確認してから送りたい場面に向いています。下書きの登録前に契約や顧客管理の記録を確認し、既に分かっている事実を相手に聞き直すのを抑える仕組みもあります。承認状況の通知は確認済みの内部宛先に限定します。

使い方の例

  • 「顧客への返信案を承認待ちとして登録する流れを設計してください」
  • 「下書き修正後は古い承認を使えないようにしてください」
  • 「送信結果が不明な場合に、自動で再送しない仕組みを組み込んでください」

注意点

参考実装はSQLiteを使い、送信サービス自体は呼び出しません。承認者の認証やデータベースの初期化は別途必要です。送信結果が不明な処理は自動再試行せず、確認して記録を照合します。保証するのは承認ごとに一度の自動送信試行で、外部への配信が必ず一度だけ完了する保証ではありません。

この紹介文は、公開されている SKILL.md をもとに AI(Claude Haiku)が作成しました。正確な仕様は下の原文を確認してください。

含まれるファイル(3)

  • SKILL.md12.8 KB
  • references/approval_claims.py7.5 KB
  • references/approval-ledger.sql14.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Operator Approval Loop

An agent that talks to external counterparties should never send on its own judgment and should keep the operator informed internally. This skill defines the contract: every outbound draft is filed as an obligation, an operator decides on the exact text, and a delivery ledger proves what went out.

When to Use

  • An agent drafts replies to customers, suppliers, investors, or partners in a shared channel, email, or chat, and a human must approve before send.
  • You need an audit trail that links each sent message to the exact draft text, the operator who approved it, and the decision time.
  • You have seen a stale approval release a rewritten draft, or two workers deliver the same approved message twice.
  • Drafts keep re-asking counterparties for facts the ledger already holds.

How It Works

Objects

ObjectMeaning
ObligationOne thing we owe a counterparty. Status moves drafted, then approved or rejected, then sent. Carries direction, counterparty, channel, and an updated_at epoch.
DraftSidecar row holding the exact draft text, a sha256 of that text, origin coordinates (platform, channel, thread, user), and priority (P0 to P3). One per obligation, replaced on re-file.
DecisionAn operator's approve or reject, recorded with the operator id, a nonce, and the draft epoch it was made against.
Approval snapshotImmutable text, hash, epoch and destination recorded by the already-authorized decision writer. Missing snapshots cannot grant dispatch.
ClaimDurable reservation with a random token and state; at most one active claim per obligation.
DeliveryLedger row proving one send or notice for one (obligation, decision) pair.

The reference schema is in references/approval-ledger.sql.

Filing a draft

  1. Clean inputs. Strip control characters, collapse whitespace in single-line fields, and enforce length caps (draft, summary, context, counterparty). Empty or oversized fields are refused, not truncated silently.
  2. Run the baseline gate (below). It may refuse the filing.
  3. Hash the draft text with sha256. The hash prefix goes into the summary so the approval panel shows which text it is approving.
  4. Upsert. If an open drafted obligation already exists for the same (counterparty, channel), replace the draft sidecar and advance the obligation's updated_at. That advance is the epoch rotation: any decision keyed to the old epoch can no longer release the new text. Otherwise insert a new obligation with status drafted.
  5. Route the filing receipt only to a configured, verified internal ops destination. If the origin is that internal destination, acknowledge there. Never-silent means internal reporting, not an automatic external reply. Keep draft hashes, approval status, operator identity and workflow metadata out of counterparty-visible channels. Unknown or unclassified origins stay quiet; a direct message is not automatically internal.

If a verified internal destination is unavailable, retain the filing result in the internal tool result or operator surface. Never fall back to an external or unknown origin. A tool result exposed to outsiders is not an internal surface.

Filing a draft does not authorize an external response. Any policy-permitted clarifying question or neutral response is a separate outbound decision, subject to the existing mention, channel, draft-only, frozen and never constraints in counterparty-channel-discipline. It must not disclose internal approval metadata.

Baseline gate

Before any draft is filed, query the current baseline for the counterparty (a temporal ledger, contract store, or CRM):

  • Signed or delivered contract on record: refuse the filing with the evidence and a recommendation. Asking a counterparty about specs after signing is the exact failure this gate exists to stop.
  • Operator override: force_despite_signed_contract lets the filing through and stamps [BASELINE_OVERRIDE_SIGNED_CONTRACT] into the draft context.
  • Gate service unreachable: the filing proceeds and the context is stamped [BASELINE_CHECK_UNAVAILABLE]. The panel sees that the guard was off. Failures never silently disable the gate.
  • When facts are available, attach the freshest few to the context as a [BASELINE FACTS: ...] digest so the draft lands with current truth.

Deciding

The approval panel lists obligations with status drafted and direction we_owe_them. Approve or reject writes a decision row carrying the draft epoch (draft_updated_ts) and flips the obligation status in the same transaction. A decision whose epoch does not match the current updated_at is stale and must not release anything.

For an already-authorized approve decision, the same transaction inserts an immutable obligation_approval_snapshots row: decision and obligation IDs, current draft epoch, exact text and SHA-256, platform/channel/thread, and kind draft_sent. The decision writer must establish authorization before writing; the reference never authenticates an operator or manufactures a decision. Automatic approval policy is not enabled or expanded by the reference. Legacy decisions without snapshots require explicit reconciliation or a new approval; never backfill permission from the current mutable draft.

Delivering

The SQLite reference is references/approval_claims.py. It grants dispatch permission but never calls transport. Use an existing local reference database initialized from the SQL fixture; the module does not apply schema or production migrations. Only a trusted decision writer may populate approval records. All writers must enable foreign keys and recursive triggers and honor the schema guards; administrative database tampering is outside this model.

  1. Discover bound approved drafts. Discovery is not permission. claim() opens its own BEGIN IMMEDIATE transaction, validates the current approved epoch, exact text, computed SHA-256 and full destination against the snapshot, and inserts a unique claim before returning its token. A conflict stops the worker before transport. Completed receipts cannot be claimed again.
  2. begin_dispatch() revalidates the binding and atomically changes claimed to dispatching using the token. Only its winning caller receives the exact draft_text and destination after commit. Never regenerate text, reread a mutable sidecar for transport, or reuse the payload for another attempt. A nested caller transaction is refused; permission cannot depend on a later caller commit. No database transaction remains open across transport.
  3. A confirmed successful result goes to complete(), which atomically records the delivery coordinate, marks the claim delivered and flips the obligation to sent. Identical completion is a no-op; conflicting coordinates fail. The receipt UNIQUE key deduplicates records, not prior external effects.
  4. Exceptions, timeouts, worker death after begin-dispatch, or failed receipt persistence leave a blocked attempt. mark_unknown() records uncertainty. Unknown claims never expire, reopen, auto-retry or allow another decision for that obligation to bypass them. A trusted caller may use reconcile() with confirmed successful coordinate and evidence; the module does not verify that evidence. An absent receipt is not proof of non-delivery.

The guarantee is one automatic dispatch attempt per approved decision, not exactly-once external delivery. A crash after begin-dispatch but before transport can leave zero sends and a held claim. Releasing an unknown outcome for a new attempt would require fencing the original executor and verifying provider semantics; this reference deliberately provides no such retry operation.

Claim stateAllowed next states
claimeddispatching or cancelled before dispatch
dispatchingdelivered or unknown
unknowndelivered through trusted reconciliation only
delivered, cancelledterminal; decision key cannot be reused

While a claim is active, database guards freeze obligation, draft and decision writes, including replacements. Snapshots and claims cannot be erased. Cancel a claimed operation with its token before re-filing; the stale token then grants nothing. After dispatch begins, hold new edits or revocation for reconciliation. This serializes changes instead of pretending to recall an in-flight operation.

Rejected decisions and legacy rows without draft sidecars/snapshots never enter this external draft-send path. Report them on the internal operator surface for manual handling. Internal receipt footers remain internal: approved by <operator> · receipt <decision_id> · draft sha256 <prefix>. Never alter already-approved external text to append workflow metadata.

Focused local validation uses temporary databases, separate connections and a simulated attempt counter, not a provider or real message: python3 -m unittest discover -s tests/skills -p 'test_approval_delivery_claims.py'. The tests require Python 3.11+ with SQLite serialization support; the reference uses only the standard library. The existing desk-pattern contract checks remain a separate compatibility check.

Time-boxed auto-approval (optional)

A draft may carry auto_send_after (epoch seconds). A sweep approves drafts whose deadline passed with no decision, recording operator auto-ttl, then delivery proceeds through the normal path. Operator actions always win: a decision flips status before the sweep sees it, and a re-file rotates the epoch and moves or clears the deadline. The sweep re-checks status and epoch inside the write transaction so a race resolves as a no-op. Drafts without a deadline stay hard-gated forever.

Signal linkage

A draft can name the inbound obligation it answers (signal_obligation_id). This is the only truthful link for latency measurement (inbound signal to drafted response) and lets the SLA scan treat that inbound item as answered. Reject the filing if the referenced row does not exist.

Examples

File a draft

file_request(
  draft="Thanks, we can hold the slot until Friday. Which start date works?",
  counterparty="acme-supplier",
  context="reply to delivery window question",
  origin_platform="slack", origin_channel="#acme-shared",
  origin_thread="1712345678.000100", priority="P1",
  signal_obligation_id=412)
-> {obligation_id: 431, draft_sha256: "9f2c...", refiled: false}

The configured, verified internal ops destination sees: Draft filed for approval (P1, sha 9f2c8a1b). Waiting on operator. The counterparty-visible origin channel receives no filing notice. If no verified internal destination is available, the receipt stays in the internal tool result or operator surface, with no external fallback.

Re-file after a steer

The operator asks for a shorter draft. Filing again for the same (counterparty, channel) returns refiled: true, the sidecar text and hash change, and updated_at advances. An approve clicked on the old panel row carries the old epoch and is ignored.

Gate refusal

DeskApprovalError: baseline gate refused this draft: the ledger shows a
signed contract for 'acme-supplier'. Evidence: master agreement executed
2026-08-14. Recommendation: do not ask. Re-file with
force_despite_signed_contract=true if this is genuinely a new thread.

Delivery footer in an internal channel

Confirmed for Friday, start date 2026-09-08.
approved by operator-a · receipt 118 · draft sha256 9f2c8a1b2d3e4f50

Invariants to test

  • Filing receipts go only to configured, verified internal ops; the origin receives one only when it is that verified internal destination.
  • An unknown origin stays quiet. An unavailable internal destination uses the internal tool result or operator surface, with no external fallback.
  • Same (counterparty, channel) filed twice yields one obligation, two epochs.
  • A decision with a stale epoch never results in a delivery row.
  • Two concurrent claimants yield one dispatch permission; losers never attempt transport.
  • Unknown outcomes and failed receipt persistence never enable an automatic retry.
  • Successful completion records the receipt and sent status in one transaction.
  • An altered epoch, text, hash or destination cannot acquire or begin a claim.
  • Active claims block re-file; only pre-dispatch cancellation can release that hold.
  • Gate unavailable stamps the marker; gate signed refuses without force.
  • Auto-ttl never fires against text the operator has since re-filed.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

accessibility

無料日本語概要

Web・iOS・Androidの画面を、読み上げやキーボード操作に対応させ、ラベル、配色、操作対象の大きさなどをWCAG 2.2に沿って設計・点検するスキル。

  • アイコンボタンの説明を付けたいとき
  • キーボード操作とモーダルの点検
  • コントラストや操作対象の大きさの確認
affaan-m/ECC27.8万2026年10月12日 更新

agent-architecture-audit

無料日本語概要

AIエージェントの不調を、指示・記憶・ツール実行・画面表示など12の層から調べるスキル。コードやログを根拠に原因を整理し、重要度順の指摘と修正案をまとめます。

  • アプリ内だけで起きる不調を調べたいとき
  • 過去の会話が混ざる原因を調査
  • ツールの未実行や実行の誤報を確認
affaan-m/ECC27.8万2026年10月12日 更新

agent-eval

無料日本語概要

実際の開発課題で複数のコーディングエージェントを比較するスキル。成功率、取得可能なAPI費用、所要時間、繰り返し実行の安定性を測り、選定や更新後の評価に使えます。

  • 実際の開発課題でエージェントを比較
  • 新しいツールやモデルの導入前評価
  • エージェント更新後の性能確認
affaan-m/ECC27.8万2026年10月12日 更新

agent-harness-construction

無料日本語概要

AIエージェントが使うツールの種類や入出力、エラーからの復帰手順を設計・見直します。文脈の情報量も整理し、作業完了率や再試行回数で改善を評価します。

  • エージェントのツールや入力形式の設計
  • ツールの結果と次の行動を明確にしたいとき
  • 安全な再試行と停止条件を定めたいとき
affaan-m/ECC27.8万2026年10月12日 更新

agent-introspection-debugging

無料日本語概要

AIエージェントが失敗や同じ操作を繰り返す原因を、エラーと実行状況から整理します。小さな復旧操作を試し、結果と根拠を引き継げる報告にまとめるスキルです。

  • エージェントの連続失敗を診断したいとき
  • 同じツール操作のループ調査
  • 情報の蓄積による出力劣化の点検
affaan-m/ECC27.8万2026年10月5日 更新

agent-introspection-debugging

無料日本語概要

AIエージェントの失敗や同じ操作の繰り返しを記録し、原因の切り分け、小さな復旧操作、結果の報告まで進める手順を示して、根拠のある再試行につなげるスキル。

  • 同じツール操作を繰り返す原因の調査
  • 会話の肥大化による品質低下の調査
  • ファイルパスや環境の食い違いの確認
affaan-m/ECC27.8万2026年10月12日 更新

affaan-m のスキルをすべて見る

このスキルの問題を報告する