Skip to content

/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

From plugin
affaan-m-ecc-2
257k200 skills68 agents109 commands7 hooks
+1
Install
$ npx -y skills add affaan-m/ECC --skill operator-approval-loop --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/operator-approval-loop

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

operator-approval-loop.SKILL.md
name: operator-approval-loop
description: 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.

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

| Object | Meaning | | --- | --- | | Obligation | One thing we owe a counterparty. Status moves `drafted`, then `approved` or `rejected`, then `sent`. Carries `direction`, `counterparty`, `channel`, and an `updated_at` epoch. | | Draft | Sidecar 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. | | Decision | An operator's approve or reject, recorded with the operator id, a nonce, and the draft epoch it was made against. | | Approval snapshot | Immutable text, hash, epoch and destination recorded by the already-authorized decision writer. Missing snapshots cannot grant dispatch. | | Claim | Durable reservation with a random token and state; at most one active claim per obligation. | | Delivery | Ledger row proving one send or notice for one (obligation, decision) pair. |

The reference schema is in [references/approval-ledger.sql](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](references/approval_claims.py). It grants dispatch permission but never calls transport. Use an existing local reference database

Read more
Ships withaffaan-m-ecc-2

Your agent can write code, but ECC gives it a coordinated engineering system and toolbox: it plans before it builds, verifies changes with tests, reviews its own work from a fresh context, remembers what matters, and turns repeated wins into reusable skills

Get the whole plugin, auto-invoked

Other skills on affaan-m-ecc-2.