{"id":19322,"plugin_id":"plugins_6a9669d9e57c8191a04a3c8951e44401","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T23:15:29.832Z","digest":"f07dd862ac9a679186ffa58aadad35c33742114de22ed1ebcb9c2b8be9961225","against":null,"payload":{"description":"Design, implement locally, or evaluate YCloud WhatsApp Calling connect, pre-accept, accept, reject, terminate, and call-media download operations. Use for API-sourced call sessions after Phone Numbers and Webhook Receiver handoffs; exclude calling settings, media upload, message operations, and real API calls.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":289},{"relative_path":"references/openapi.md","size_in_bytes":18542},{"relative_path":"references/runtime.md","size_in_bytes":16520},{"relative_path":"references/shared/integration-boundaries.md","size_in_bytes":8401}],"name":"ycloud-whatsapp-calling","skill_md_contents":"---\nname: ycloud-whatsapp-calling\ndescription: Design, implement locally, or evaluate YCloud WhatsApp Calling connect, pre-accept, accept, reject, terminate, and call-media download operations. Use for API-sourced call sessions after Phone Numbers and Webhook Receiver handoffs; exclude calling settings, media upload, message operations, and real API calls.\n---\n\n# YCloud WhatsApp Calling\n\nDesign or implement contract-aware WhatsApp Calling session commands and call\nmedia downloads. Keep every example synthetic and every transport mock-only;\nnever call YCloud or Meta, inspect credentials or customer data, or claim that a\nreal call changed state.\n\n## Execution boundary\n\nThese restrictions govern Skill execution: do not call a YCloud Provider API, access real credentials, or read real business data. The Skill may generate server-side adapter code for an application's runtime, but must not start it or make a live request. Reading public official documentation as contract evidence is allowed and is not a Provider API call or business-data access. A live smoke test is outside the default workflow and requires separate, explicit authorization naming the target/environment, allowed operations, credential boundary, and required result evidence.\n\nHonor Architect handoffs for scope, deliverable, mutation, capability IDs,\nproject seams, and evidence. Without one, default to focused read-only guidance\nunless the user explicitly requests local implementation. Local-write\nauthorization permits trusted-server request builders, adapters, handlers,\nstate models, synthetic webhook fixtures, mock transports, and no-network tests\ninside the scoped project. It never authorizes a real call command or media\ndownload.\n\nAfter this Skill is selected, read the generated [OpenAPI\ncontract](references/openapi.md) and reviewed [runtime\nbehavior](references/runtime.md). If retry, idempotency, queueing, error\ntranslation, or production architecture is requested, also read\n`references/shared/integration-boundaries.md`. If either Calling reference is\nmissing, stale, or inconsistent with the pinned source hash and operation count,\nreport drift and stop rather than reconstructing the contract from memory.\n\n## Exact operation scope\n\n| Intent | Method and path | operationId |\n| --- | --- | --- |\n| Connect an outbound call | `POST /whatsapp/calls/connect` | `whatsapp_call-connect` |\n| Pre-accept an inbound call | `POST /whatsapp/calls/preAccept` | `whatsapp_call-pre-accept` |\n| Accept an inbound call | `POST /whatsapp/calls/accept` | `whatsapp_call-accept` |\n| Reject an inbound call | `POST /whatsapp/calls/reject` | `whatsapp_call-reject` |\n| Terminate an active call | `POST /whatsapp/calls/terminate` | `whatsapp_call-terminate` |\n| Download call recording/transcription | `GET /whatsapp/calls/media/{mediaAssetId}` | `whatsapp_call-download-media` |\n\nCalling/capture configuration belongs to `ycloud-whatsapp-phone-numbers`.\nWebhook signature verification, raw-body handling, durable acceptance,\ndeduplication, and event parsing belong to the Webhook Receiver. Media upload\nbelongs to `ycloud-whatsapp-media`; WhatsApp message submission and message IDs\nbelong to `ycloud-whatsapp-messages`; authentication belongs to\n`ycloud-api-authentication`; broad multi-domain planning belongs to\n`ycloud-integration-architect`.\n\n## Required incoming handoffs\n\n- **Phone Numbers:** consume a separately confirmed WhatsApp Business\n  `phoneId`, source E.164 phone number, and Calling/capture readiness evidence.\n  Settings or registration success is only prerequisite evidence; it does not\n  authorize a call command or prove that a call can connect.\n- **Webhook Receiver:** consume only a signature-verified, durably accepted,\n  deduplicated call event. For inbound pre-accept, accept, reject, or terminate,\n  take `wacid` and `phoneId` from the parsed Call Connect/session event. For a\n  recording or transcription, take `mediaAssetId`, `wacid`, `phoneId`, and\n  `status` from the parsed media event. Do not alter the Receiver's already\n  issued HTTP acknowledgement.\n\nNever substitute one identifier for another. Keep these opaque, case-sensitive\nvalues in separately named fields:\n\n- `wacid`: WhatsApp call/session ID.\n- `phoneId`: WhatsApp Business phone-number ID; not an E.164 phone number.\n- `from` and `to`: E.164 phone-number strings; never numeric values.\n- `recipient`: BSUID or parent BSUID; not a phone, call, message, or event ID.\n- `event.id`: webhook envelope event ID; never a call-command identifier.\n- message IDs and application correlation IDs: unrelated to Calling commands.\n- `mediaAssetId`: call recording/transcription asset ID; only this value belongs\n  in the media-download path.\n\n## Contract-first workflow\n\n1. Match only the six allowlisted operations. Report the pinned source hash,\n   exact method/path, `operationId`, request schema, response schema, and\n   description-only behavior. An `operationId` is not an SDK method name.\n2. For outbound `connect`, require `from`, `sdpType: \"offer\"`, and SDP. Preserve\n   the contract's `to`/`recipient` rule: provide exactly one; if an upstream\n   caller supplies both, `to` takes precedence and `recipient` is ignored. Do\n   not convert phone strings or BSUIDs into another identifier type.\n3. For inbound `preAccept` and `accept`, require `phoneId`, `wacid`,\n   `sdpType: \"answer\"`, and SDP. Pre-accept establishes the media connection to\n   reduce connection time/audio clipping; accept begins media flow after the\n   WebRTC connection. Do not skip local session-order validation merely because\n   both endpoints share a request schema.\n4. For `reject` and `terminate`, require only `phoneId` and `wacid`. Reject is\n   for an incoming call; terminate is for an active call. Treat choosing the\n   wrong lifecycle command as an application error, not as a retry strategy.\n5. A `200` Calling response requires `success` and may return `wacid`. Interpret\n   it only as the selected command being accepted or processed. It is not proof\n   of ringing, connection, media flow, termination visibility, or any final session state.\n   Correlate later verified call events by `wacid`, preserve\n   duplicate/out-of-order/unknown states, and keep command records separate\n   from the event-derived session projection.\n6. Download call media only after a recording/transcription event reports\n   `status: AVAILABLE` and supplies its own `mediaAssetId`. Encode that opaque ID\n   as one path segment. Omit `Range` or send it blank; a non-empty `Range` is a\n   documented `400` because byte ranges are unsupported. A `200` is the complete\n   attachment, `Accept-Ranges` is `none`, recordings use `.ogg`, transcriptions\n   use `.json`, and the owning tenant can download for 30 days. Treat `404` as\n   intentionally non-disclosing across missing, unavailable, expired, or\n   wrong-tenant assets.\n7. Preserve the standard error envelope and redacted `YCloud-Request-ID` /\n   `error.requestId`. Branch on HTTP status and `error.code`, never expose the\n   diagnostic `error.message` directly to end users, and preserve unknown\n   properties, event types, and statuses.\n8. Do not automatically replay any Calling POST after timeout, connection loss,\n   `429`, or an ambiguous response. `Retry-After` delays later traffic but does\n   not make replay safe. A provider `retryable` flag on failed media processing\n   concerns the upstream media operation; it does not authorize replay of a\n   call command or download request. Require fresh session evidence and an\n   explicit application-owned decision before any new command.\n9. Use placeholders such as `<YCLOUD_API_KEY>`, `<PHONE_ID>`,\n   `<SYNTHETIC_WACID>`, `<E164_PHONE_NUMBER>`, and `<MEDIA_ASSET_ID>`. Tests must\n   use a fake transport that fails closed on real base URLs, credentials, or\n   network clients.\n\n## Media download handoff\n\nProduce a typed handoff only after verified `whatsapp.call.recording.updated` or\n`whatsapp.call.transcription.updated` evidence:\n\n- event type, webhook `event.id`, `wacid`, `phoneId`, `mediaAssetId`, and\n  `AVAILABLE` status, each in a separate field;\n- owning-tenant context, media kind, 30-day expiry/freshness evidence, and the\n  mock-only download authorization decision;\n- complete-file semantics, expected `.ogg` or `.json` attachment, no byte-range\n  support, redacted request ID, and destination/storage policy owned by the\n  consuming application.\n\nOn `FAILED`, retain the structured `error.code` and `error.retryable` evidence\nbut do not construct a download request. Never pass `wacid`, `phoneId`, a\nmessage ID, or `event.id` as `mediaAssetId`.\n\n## Validation and evidence\n\nFor local implementation, add no-network tests for all six routes; exact body\nrequiredness; `offer` versus `answer`; `to`/`recipient` precedence; opaque ID and\nE.164 preservation; lifecycle command selection; command acceptance versus\nevent-derived final state; duplicate/out-of-order/unknown events; timeout and\n`429` no-replay behavior; standard errors/request IDs; `AVAILABLE` versus\n`FAILED`; 30-day media eligibility; blank/non-empty `Range`; complete binary\nresponses and attachment metadata; `404` nondisclosure; and rejection of every\ncross-ID substitution. Mocks must prove no network client is invoked.\n\nReturn these sections, adapted to the requested deliverable: **Matched\ncontract**, **Incoming handoffs**, **Construction or implementation**,\n**Command versus session state**, **Media download handoff**, **Tests and\nevidence**, **CANNOT**, and **Handoff**. Return capability status, artifacts,\nresults, unknowns, and outgoing handoffs to Architect when applicable.\n\n## Safety stop\n\nYCloud Provider API calls are prohibited during Skill execution, including the\nmedia GET. Stop before any request using a real key, tenant, phone, call, event,\nmessage, media, SDP, or customer identifier. Never claim a call or media\nsession changed in production.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}