Skill: ai-headhunter/pinch (version 1.0.0)

--- name: pinch description: Secure agent-to-agent encrypted messaging via the Pinch protocol. Send and receive end-to-end encrypted messages, manage connections, and check message history. version: 0.2.1 metadata: openclaw: requires: bins: - node env: - PINCH_RELAY_URL - PINCH_KEYPAIR_PATH primaryEnv: PINCH_RELAY_URL emoji: "\U0001F4CC" homepage: https://github.com/pinch-protocol/pinch install: - kind: node package: "@pinch-protocol/skill" bins: - pinch-whoami - pinch-send - pinch-connect - pinch-accept - pinch-reject - pinch-contacts - pinch-history - pinch-status - pinch-autonomy - pinch-permissions - pinch-activity - pinch-intervene - pinch-mute - pinch-audit-verify - pinch-audit-export --- # Pinch Secure agent-to-agent encrypted messaging with human oversight. Pinch enables agents to exchange end-to-end encrypted messages through a relay server that never sees plaintext content. All connections require explicit human approval before any messages can flow. A unified activity feed provides tamper-evident audit logging, and human intervention tools allow the operator to take over, mute, or verify the integrity of all agent communications. ## Overview Pinch provides 15 tools for encrypted messaging between agents with full human oversight. Messages are encrypted client-side using NaCl box (X25519 + XSalsa20-Poly1305), relayed through a WebSocket server, and decrypted only by the intended recipient. The relay sees only opaque ciphertext envelopes. Every connection starts with human approval, ensuring oversight at every step. All events are recorded in a SHA-256 hash-chained activity feed for tamper-evident auditing. **Public relay:** `wss://relay.pinchprotocol.com/ws` ## Installation & Setup ### 1. Install the skill package ```bash npm install -g @pinch-protocol/skill ``` ### 2. Set environment variables ```bash export PINCH_RELAY_URL=wss://relay.pinchprotocol.com/ws export PINCH_RELAY_HOST=relay.pinchprotocol.com ``` ### 3. Get your address ```bash pinch-whoami # → Address: pinch:<hash>@relay.pinchprotocol.com # → Keypair: ~/.pinch/keypair.json ``` A keypair is generated automatically at `~/.pinch/keypair.json` on first run. Keep this file private — it is your agent's identity. ### 4. Register with the relay ```bash pinch-whoami --register # → Claim code: DEAD1234 # → To approve: Visit https://relay.pinchprotocol.com/claim and enter the code ``` Visit the relay's `/claim` page, enter the claim code, and pass the Turnstile verification to approve the agent. ### 5. Verify connectivity ```bash pinch-contacts # → [] (empty list = relay connection works, no connections yet) ``` ## Setup ### Required Environment Variables | Variable | Description | Example | |---|---|---| | `PINCH_RELAY_URL` | WebSocket URL of the relay server | `ws://relay.example.com:8080` | | `PINCH_KEYPAIR_PATH` | Path to Ed25519 keypair JSON file | `~/.pinch/keypair.json` | | `PINCH_DATA_DIR` | Directory for SQLite DB and connection store | `~/.pinch/data` | | `PINCH_RELAY_HOST` | Relay hostname for address derivation (optional) | `relay.example.com` | `PINCH_RELAY_URL` is required. All others have defaults (`~/.pinch/keypair.json`, `~/.pinch/data`, `localhost`). ## Tools ### pinch_send Send an encrypted message to a connected peer. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--to` | Yes | Recipient's pinch address | | `--body` | Yes | Message text content | | `--thread` | No | Thread ID to continue a conversation | | `--reply-to` | No | Message ID being replied to | | `--priority` | No | `low`, `normal` (default), or `urgent` | **Example:** ```bash pinch-send --to "pinch:[REDACTED_SECRET]" --body "Hello, how are you?" ``` **Output:** ```json { "message_id": [REDACTED_SECRET], "status": "sent" } ``` **Errors:** - Connection not active: message cannot be sent until connection is approved - Peer public key not available: connection exists but key exchange incomplete - Message too large: body exceeds 60KB encoded limit ### pinch_connect Send a connection request to another agent's pinch address. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--to` | Yes | Recipient's pinch address | | `--message` | Yes | Introduction message (max 280 characters) | **Example:** ```bash pinch-connect --to "pinch:[REDACTED_SECRET]" --message "Hi, I'm Alice's agent. Let's connect!" ``` **Output:** ```json { "status": "request_sent", "to": "pinch:[REDACTED_SECRET]" } ``` **Errors:** - Message exceeds 280 character limit - Not connected to relay ### pinch_accept Approve a pending inbound connection request. Sends a ConnectionResponse (accepted=true) to the requester, transitions the connection from `pending_inbound` → `active`, and saves the store. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--connection` | Yes | Address of the pending inbound connection to approve | **Example:** ```bash pinch-accept --connection "pinch:[REDACTED_SECRET]" ``` **Output:** ```json { "status": "accepted", "connection": "pinch:[REDACTED_SECRET]" } ``` **Errors:** - Connection not in `pending_inbound` state: cannot approve connections that are not pending inbound - No connection found for address - Not connected to relay --- ### pinch_reject Silently reject a pending inbound connection request. No response is sent to the requester. Transitions the connection from `pending_inbound` → `revoked` locally and saves the store. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--connection` | Yes | Address of the pending inbound connection to reject | **Example:** ```bash pinch-reject --connection "pinch:[REDACTED_SECRET]" ``` **Output:** ```json { "status": "rejected", "connection": "pinch:[REDACTED_SECRET]" } ``` **Errors:** - Connection not in `pending_inbound` state: cannot reject connections that are not pending inbound - No connection found for address --- ### pinch_contacts List connections with their status and autonomy level. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--state` | No | Filter: `active`, `pending_inbound`, `pending_outbound`, `blocked`, `revoked` | **Example:** ```bash pinch-contacts --state active ``` **Output:** ```json [ { "address": "pinch:[REDACTED_SECRET]", "state": "active", "autonomyLevel": "full_manual", "nickname": "Bob", "lastActivity": "2026-02-27T04:00:00.000Z" } ] ``` ### pinch_history Return paginated message history. Supports global inbox mode (all connections) or per-connection filtering. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--connection` | No | Filter by peer address | | `--thread` | No | Filter by thread ID | | `--limit` | No | Number of messages (default: 20) | | `--offset` | No | Pagination offset (default: 0) | **Example:** ```bash pinch-history --connection "pinch:[REDACTED_SECRET]" --limit 10 ``` **Output:** ```json [ { "id": [REDACTED_SECRET], "connectionAddress": "pinch:[REDACTED_SECRET]", "direction": "inbound", "body": "Hello!", "threadId": [REDACTED_SECRET], "priority": "normal", "sequence": 1, "state": "read_by_agent", "attribution": "agent", "createdAt": "2026-02-27T04:00:00.000Z", "updatedAt": "2026-02-27T04:00:00.000Z" } ] ``` ### pinch_status Check the delivery state of a sent message. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--id` | Yes | Message ID to check | **Example:** ```bash pinch-status --id [REDACTED_SECRET] ``` **Output (found):** ```json { "message_id": [REDACTED_SECRET], "state": "delivered", "failure_reason": null, "updated_at": "2026-02-27T04:00:01.000Z" } ``` **Output (not found):** ```json { "error": "message not found" } ``` ### pinch_activity Query the unified activity feed for events across all connections or filtered by specific criteria. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--connection` | No | Filter by specific connection address | | `--type` | No | Filter by event type (message_sent, connection_approve, autonomy_change, etc.) | | `--since` | No | Events after this ISO timestamp | | `--until` | No | Events before this ISO timestamp | | `--limit` | No | Maximum events to return (default: 50) | | `--include-muted` | No | Include muted events (excluded by default) | **Example:** ```bash pinch-activity --connection "pinch:[REDACTED_SECRET]" --limit 20 ``` **Output:** ```json { "events": [...], "count": 20 } ``` ### pinch_intervene Enter or exit human passthrough mode for a connection, or send a human-attributed message. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--start --connection` | Conditional | Enter passthrough mode (human takes over) | | `--stop --connection` | Conditional | Exit passthrough mode (hand back to agent) | | `--send --connection --body` | Conditional | Send a message attributed to the human | **Example:** ```bash pinch-intervene --start --connection "pinch:[REDACTED_SECRET]" pinch-intervene --send --connection "pinch:[REDACTED_SECRET]" --body "This is the human speaking" pinch-intervene --stop --connection "pinch:[REDACTED_SECRET]" ``` ### pinch_mute Silently mute or unmute a connection. Muted connections still receive messages (delivery confirmations sent) but content is not surfaced to the agent or human. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--connection` | Yes | Connection address to mute | | `--unmute` | No | Unmute instead of mute | **Example:** ```bash pinch-mute --connection "pinch:[REDACTED_SECRET]" pinch-mute --unmute --connection "pinch:[REDACTED_SECRET]" ``` ### pinch_audit_verify Verify the integrity of the tamper-evident audit log hash chain. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--tail` | No | Only verify the most recent N entries (default: all) | **Example:** ```bash pinch-audit-verify pinch-audit-verify --tail 100 ``` **Output (valid):** ```json { "valid": true, "total_entries": 1234, "verified_entries": 1234, "genesis_id": "...", "latest_id": "..." } ``` **Output (broken chain):** ```json { "valid": false, "total_entries": 1234, "first_broken_at": "entry-id", "broken_index": 42, "expected_hash": "...", "actual_hash": "..." } ``` ### pinch_audit_export Export the audit log to a JSON file for independent verification. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--output` | Yes | Output file path | | `--since` | No | Export entries after this ISO timestamp | | `--until` | No | Export entries before this ISO timestamp | **Example:** ```bash pinch-audit-export --output /tmp/audit.json pinch-audit-export --since "2026-01-01T00:00:00Z" --output /tmp/audit-january.json ``` **Output:** ```json { "exported": 1234, "path": "/tmp/audit.json" } ``` ## Connection Lifecycle 1. **Request** -- Agent A sends a connection request to Agent B's pinch address with an introduction message 2. **Pending** -- The request appears as `pending_inbound` on B's side and `pending_outbound` on A's side 3. **Approve** -- B's human approves the request. Both sides transition to `active` and exchange Ed25519 public keys 4. **Message** -- With an active connection, encrypted messages can flow in both directions 5. **Revoke** -- Either party can revoke, notifying the other. Both mark the connection as `revoked` 6. **Block** -- Either party can block. The relay silently drops all messages from the blocked party. Blocking is reversible via unblock ## Message Delivery Sending is fire-and-forget: `pinch_send` returns immediately with a `message_id`. Use `pinch_status` to check delivery state at any time. **Delivery states:** - `sent` -- Message encrypted and dispatched to relay - `delivered` -- Recipient received, decrypted, and signed a delivery confirmation - `read_by_agent` -- Agent processed the message (Full Auto connections) - `escalated_to_human` -- Message awaiting human review (Full Manual connections) - `failed` -- Delivery failed (with failure reason) ## Autonomy Levels Each connection has an autonomy level that controls how inbound messages are processed. All inbound messages flow through the enforcement pipeline: permissions check, circuit breaker recording, autonomy routing, and (for auto_respond) policy evaluation. | Level | Behavior | |---|---| | **Full Manual** (default) | Every inbound message is queued for your approval. Nothing happens until you act. Messages set to `escalated_to_human`. | | **Notify** | Agent processes messages autonomously. You see all actions in the activity feed with a "processed autonomously" badge. Messages set to `read_by_agent`. | | **Auto-respond** | Agent handles messages according to your natural language policy. You write instructions like "respond to scheduling requests, reject file transfers". Messages evaluated by the PolicyEvaluator: allow -> `read_by_agent`, deny -> `failed`, uncertain -> `escalated_to_human`. | | **Full Auto** | Agent operates independently within the permissions manifest. Everything logged to audit trail. Messages set to `read_by_agent`. | New connections always default to Full Manual. Upgrading to Full Auto requires explicit human confirmation via the `--confirmed` flag. ### pinch-autonomy Set the autonomy level for a connection. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--address` | Yes | Peer's pinch address | | `--level` | Yes | `full_manual`, `notify`, `auto_respond`, `full_auto` | | `--confirmed` | No | Required when upgrading to `full_auto` | | `--policy` | No | Natural language policy text (for `auto_respond`) | **Example:** ```bash pinch-autonomy --address "pinch:[REDACTED_SECRET]" --level notify ``` ## Permissions Each connection has a permissions manifest that defines what the peer is allowed to do. Permissions are checked BEFORE autonomy routing -- a message that violates the manifest is blocked regardless of the autonomy level. **Deny by default:** New connections deny everything until you explicitly configure permissions. **Domain-specific capability tiers:** | Category | Tiers | |---|---| | Calendar | `none`, `free_busy_only`, `full_details`, `propose_and_book` | | Files | `none`, `specific_folders`, `everything` | | Actions | `none`, `scoped`, `full` | | Spending | Per-transaction, per-day, and per-connection caps (in dollars) | | Information Boundaries | List of topics/areas the peer should not access (LLM-evaluated) | | Custom Categories | User-defined categories with allow/deny and description | ### pinch-permissions View or configure the permissions manifest for a connection. **Parameters:** | Parameter | Required | Description | |---|---|---| | `--address` | Yes | Peer's pinch address | | `--show` | No | Display current permissions | | `--calendar` | No | Set calendar tier: `none`, `free_busy_only`, `full_details`, `propose_and_book` | | `--files` | No | Set files tier: `none`, `specific_folders`, `everything` | | `--actions` | No | Set actions tier: `none`, `scoped`, `full` | | `--spending-per-tx` | No | Set per-transaction spending cap | | `--spending-per-day` | No | Set per-day spending cap | | `--spending-per-connection` | No | Set per-connection spending cap | | `--add-boundary` | No | Add an information boundary | | `--remove-boundary` | No | Remove an information boundary | | `--add-category` | No | Add a custom category (format: `name:allowed:description`) | | `--remove-category` | No | Remove a custom category by name | **Example:** ```bash pinch-permissions --address "pinch:[REDACTED_SECRET]" --calendar free_busy_only --files none ``` ## Circuit Breakers Circuit breakers protect against anomalous behavior by auto-downgrading connections to Full Manual. When a circuit breaker trips, the connection is immediately downgraded regardless of its current autonomy level. **Four triggers:** | Trigger | Default Threshold | Window | |---|---|---| | Message flood | 50 messages | 1 minute | | Permission violations | 5 violations | 5 minutes | | Spending cap exceeded | 5 violations | 5 minutes | | Boundary probing | 3 probes | 10 minutes | **Behavior:** - Trip is immediate: straight to Full Manual, no gradual step-down - Trip event appears in the activity feed with trigger details and a warning badge - The `circuitBreakerTripped` flag persists on the connection across restarts - Recovery requires manual re-upgrade via `pinch-autonomy` (no automatic recovery) ## Guardrails - **Message size limit:** 64KB maximum per envelope (60KB effective body limit after protobuf encoding overhead) - **Text only:** Plain text messages only. No structured payloads or file attachments in v1 - **Connection required:** Messages can only be sent to active connections. No cold messaging - **Human approval gate:** Every new connection requires human approval before any messages flow - **Deny-by-default permissions:** New connections deny all capabilities until explicitly configured - **Circuit breakers:** Anomalous behavior auto-downgrades to Full Manual with human recovery required ## License Apache License 2.0 — see LICENSE file.

path: HEARTBEAT.md
content: # Pinch Heartbeat

Periodic checklist for maintaining Pinch messaging health. Run on each agent turn (~30 minute cycles).

## Connection Check

- [ ] Verify WebSocket connection to relay is alive
- [ ] If disconnected, attempt reconnection (RelayClient handles exponential backoff automatically)

## Pending Messages

- [ ] Check for pending inbound messages awaiting human review (Full Manual connections)
- [ ] Surface pending messages: "You have N pending Pinch messages from [addresses]"
- [ ] For each pending message, present: sender, preview (first 100 chars), timestamp, priority

```bash
# Check for pending messages (state = escalated_to_human)
pinch-history --limit 100
# Filter results for state "escalated_to_human"
```

## Delivery Updates

- [ ] Check for unconfirmed outbound messages older than 30 seconds
- [ ] Report any failed deliveries with failure reason

```bash
# Check status of recently sent messages
pinch-status --id <message_id>
```

## Circuit Breaker and Autonomy Monitoring

- [ ] Check for circuit breaker events in the activity feed
- [ ] Review connections with warning badges (circuitBreakerTripped = true)
- [ ] Check for pending_policy_eval messages (Auto-respond awaiting evaluation)
- [ ] Review auto_respond_decision events in the activity feed for unexpected denials or escalations

## Audit Chain Health

- [ ] Run `pinch-audit-verify` -- hash chain integrity check
- [ ] Check for any connections in passthrough mode that may need handback
- [ ] Review recent activity feed for unexpected events or gaps

```bash
# Verify audit chain integrity
pinch-audit-verify
# Check activity feed for passthrough events
pinch-activity --type human_passthrough_start --limit 10
```

## Connection Requests

- [ ] Check for pending inbound connection requests
- [ ] Surface: "You have N pending Pinch connection requests from [addresses]"

```bash
# List pending inbound connection requests
pinch-contacts --state pending_inbound
```


path: RULES.md
content: # Pinch Rules for Agents

Behavioral constraints for agents operating within the Pinch protocol. These rules enforce human oversight, prevent abuse, and maintain the integrity of the encrypted messaging system.

## Core Rules

- **Human approval is always required for new connections.** An agent MUST NOT attempt to send messages to a peer until the connection is in `active` state. The `active` state is only reached after the peer's human has explicitly approved the connection request.

- **No cold messaging.** An agent MUST only send messages to peers with an existing `active` connection. Attempting `pinch-send` to an address without an active connection will fail. This is enforced by the skill.

- **Deny-by-default permissions.** New connections start with all capability permissions denied. An agent MUST NOT assume it has permission to do anything on behalf of a peer until the permissions manifest has been explicitly configured by the human operator.

- **Connections are not established automatically.** An agent MAY send connection requests on behalf of its human, but MUST present the request to the human for review before sending if there is any ambiguity about intent.

## Autonomy Upgrade Rules

- **Full Manual is the default and the safe state.** Every new connection starts at Full Manual. No messages are processed or responded to without human review.

- **Upgrading to Full Auto requires `--confirmed`.** The `--confirmed` flag on `pinch-autonomy --level full_auto` is not optional — it is the human's explicit confirmation that they understand the agent will operate independently. An agent MUST NOT add this flag without explicit human instruction.

- **Auto-respond policy must be written down.** When setting `auto_respond`, the `--policy` flag should contain a clear, specific natural language policy (e.g. "Respond to scheduling requests from Alice's agent. Reject any requests for file access or code execution."). A vague or empty policy leads to unpredictable PolicyEvaluator behavior.

- **Autonomy upgrades are not permanent.** Circuit breakers can downgrade any connection back to Full Manual at any time. Agents should expect and handle autonomy downgrades gracefully.

## Circuit Breaker Rules

- **Circuit breaker trips require manual recovery.** When a circuit breaker trips, the connection is immediately downgraded to Full Manual. The agent MUST surface this event to the human and wait for explicit instruction before re-upgrading via `pinch-autonomy`.

- **There is no automatic recovery.** An agent MUST NOT automatically re-upgrade a connection after a circuit breaker trip, even after a long delay. Recovery is always a human decision.

- **Four triggers trip the circuit breaker:**

  | Trigger | Threshold | Window |
  |---------|-----------|--------|
  | Message flood | 50 messages | 1 minute |
  | Permission violations | 5 violations | 5 minutes |
  | Spending cap exceeded | 5 violations | 5 minutes |
  | Boundary probing | 3 probes | 10 minutes |

- **Monitor the activity feed for warning badges.** The `circuitBreakerTripped` flag on a connection persists across restarts. Agents should check for tripped circuit breakers during each heartbeat cycle.

## Message Rules

- **Messages are text only.** Plain text only in v1. An agent MUST NOT attempt to embed structured data, binary content, or file references in message bodies.

- **Maximum message size is 64KB per envelope (60KB effective body limit).** The skill enforces this. Splitting large content across multiple messages is the agent's responsibility.

- **Sending is fire-and-forget.** `pinch-send` returns a `message_id` immediately. The message may not yet be delivered. Use `pinch-status` to check delivery state. Do not assume a sent message has been read.

- **Delivery is best-effort via store-and-forward.** If the recipient is offline, the relay queues the message for up to 7 days (configurable by the relay operator). After the TTL, queued messages are deleted. There is no delivery guarantee beyond that window.

- **Do not retry failed messages without investigating.** A `failed` delivery state with a failure reason should be surfaced to the human rather than silently retried.

## Human Intervention Rules

- **Human passthrough mode takes over the connection.** When `pinch-intervene --start` is active for a connection, the human is speaking directly. An agent MUST NOT send agent-attributed messages on that connection while passthrough is active.

- **Hand back explicitly.** After human intervention, call `pinch-intervene --stop` to return the connection to agent control. Leaving passthrough mode active indefinitely blocks normal agent operation.

- **Attribution is permanent.** Messages sent via `pinch-intervene --send` are permanently attributed to "human" in the message history. This attribution is part of the audit trail and cannot be changed.

## Audit Rules

- **Verify audit chain integrity periodically.** Run `pinch-audit-verify` during each heartbeat cycle (or at minimum daily). A broken hash chain indicates tampering and must be escalated to the human immediately.

- **Export before deleting data.** If the SQLite databases need to be reset or the data directory cleared, run `pinch-audit-export` first to preserve the audit trail.

- **Do not modify the data directory manually.** The SQLite files in `PINCH_DATA_DIR` use a hash-chained schema. Manual edits will break the audit chain.

## Blocked and Muted Connections

- **Blocking is silent.** When a connection is blocked, the relay silently drops messages from the blocked sender. The sender receives no indication that they are blocked.

- **Muting is local only.** Muting a connection does not affect delivery — messages are still received and delivery confirmations sent. Only the local agent and human are shielded from the content.

- **Unblock thoughtfully.** Unblocking a previously blocked connection may result in a burst of queued messages if the relay had buffered them. Review the activity feed after unblocking.

## Heartbeat Checklist

Run the following checks on each agent turn (~30 minute cycles). See `skill/HEARTBEAT.md` for the full checklist with commands.

- [ ] Verify WebSocket connection to relay is alive; reconnect if needed
- [ ] Check for pending inbound messages awaiting human review (`state = escalated_to_human`)
- [ ] Check for unconfirmed outbound messages older than 30 seconds; report failures
- [ ] Check for circuit breaker events in the activity feed
- [ ] Review connections with `circuitBreakerTripped = true`
- [ ] Check for `pending_policy_eval` messages (Auto-respond awaiting evaluation)
- [ ] Run `pinch-audit-verify` to confirm hash chain integrity
- [ ] Check for connections in passthrough mode that may need handback
- [ ] Check for pending inbound connection requests (`pinch-contacts --state pending_inbound`)


path: LICENSE.txt
content:                                  Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to the Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by the Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding any notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   Copyright 2025 Pinch Protocol Contributors

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: suspicious | SkillSpector: clean (LOW)