{"id":19326,"plugin_id":"plugins_6a9669d9e57c8191a04a3c8951e44401","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T23:15:29.907Z","digest":"9d0900774dc3658522f07c7b9536b8d57f14b0503278816fce8cac58f4d711a7","against":null,"payload":{"description":"Design, implement locally, or evaluate all 12 YCloud WhatsApp Groups operations, including asynchronous lifecycle tracking, join requests, participants, settings, invite links, and the invite-link message handoff. Use for group management; exclude ordinary or Flow message sending, Flow lifecycle, and real API mutations.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":301},{"relative_path":"references/openapi.md","size_in_bytes":98329},{"relative_path":"references/runtime.md","size_in_bytes":14605},{"relative_path":"references/shared/integration-boundaries.md","size_in_bytes":8401},{"relative_path":"references/shared/pagination-contract.md","size_in_bytes":3494}],"name":"ycloud-whatsapp-groups","skill_md_contents":"---\nname: ycloud-whatsapp-groups\ndescription: Design, implement locally, or evaluate all 12 YCloud WhatsApp Groups operations, including asynchronous lifecycle tracking, join requests, participants, settings, invite links, and the invite-link message handoff. Use for group management; exclude ordinary or Flow message sending, Flow lifecycle, and real API mutations.\n---\n\n# YCloud WhatsApp Groups\n\nDesign or implement contract-aware WhatsApp group management against mocks only.\nNever call YCloud, perform a real group or message mutation, read credentials or\ncustomer data, or claim that an accepted request reached its final state.\n\n## Execution and authority 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 an Architect handoff for `scope`, `deliverable`, `mutation`, capability\nIDs, project seams, and evidence. Without one, default to focused, read-only\nguidance unless the user explicitly requests local implementation. Local-write\nauthorization permits request models/builders, adapters, handlers, service\nbindings, mocks, fixtures, and no-network tests inside the scoped project. Every\nmutating operation remains mock-only; local-write authorization does not\nauthorize a real create, delete, update, participant action, invite-link reset,\njoin-request action, or message send.\n\nKeep claims in three authority layers:\n\n1. **Provider contract** — [references/openapi.md](references/openapi.md) and\n   [references/runtime.md](references/runtime.md). State these as YCloud behavior.\n2. **Developer Kit policy** — `references/shared/integration-boundaries.md` when\n   retry, idempotency, queueing, error translation, or webhook reliability is in\n   scope. Label its recommendations as local policy.\n3. **Project decisions** — only facts confirmed in the user's scoped project.\n\nDo not promote an `operationId`, generated model name, `x-*` extension, example,\nplatform recommendation, or project convention into provider behavior. If the\ngenerated references are absent, stale, internally inconsistent, or do not list\nall 12 operations below, stop and report the drift.\n\n## Exact operation allowlist\n\nLoad both generated references after this Skill is selected. Match only these\noperations and preserve every source-defined path parameter, query parameter,\nrequest/response schema, status code, and description constraint.\nFor either list operation, also read\n[`references/shared/pagination-contract.md`](references/shared/pagination-contract.md).\n\n| Intent | Method and path | operationId |\n| --- | --- | --- |\n| Create group | `POST /whatsapp/{businessPhoneNumber}/groups` | `whatsapp_group-create` |\n| List groups | `GET /whatsapp/{businessPhoneNumber}/groups` | `whatsapp_group-list` |\n| Retrieve group | `GET /whatsapp/{businessPhoneNumber}/groups/{groupId}` | `whatsapp_group-retrieve` |\n| Delete group | `DELETE /whatsapp/{businessPhoneNumber}/groups/{groupId}` | `whatsapp_group-delete` |\n| Retrieve invite link | `GET /whatsapp/{businessPhoneNumber}/groups/{groupId}/inviteLink` | `whatsapp_group-retrieve-invite-link` |\n| Reset invite link | `POST /whatsapp/{businessPhoneNumber}/groups/{groupId}/inviteLink/reset` | `whatsapp_group-reset-invite-link` |\n| Send invite-link message | `POST /whatsapp/{businessPhoneNumber}/groups/inviteLink/messages` | `whatsapp_group-send-invite-link-message` |\n| List join requests | `GET /whatsapp/{businessPhoneNumber}/groups/{groupId}/joinRequests` | `whatsapp_group-list-join-requests` |\n| Approve join requests | `POST /whatsapp/{businessPhoneNumber}/groups/{groupId}/joinRequests/approve` | `whatsapp_group-approve-join-requests` |\n| Reject join requests | `POST /whatsapp/{businessPhoneNumber}/groups/{groupId}/joinRequests/reject` | `whatsapp_group-reject-join-requests` |\n| Update settings | `PATCH /whatsapp/{businessPhoneNumber}/groups/{groupId}/settings` | `whatsapp_group-update-settings` |\n| Remove participants | `POST /whatsapp/groups/{groupId}/participants/remove` | `whatsapp_group-remove-participants` |\n\nThe participant-removal path intentionally omits `{businessPhoneNumber}`. Do\nnot normalize it to the shape of the other endpoints. Group conversation message\ncomposition or sending belongs to `ycloud-whatsapp-messages`; only the dedicated\ninvite-link-message operation remains in this Skill. Flow lifecycle belongs to\n`ycloud-whatsapp-flows`.\n\n## Contract-first workflow\n\n1. Confirm the selected operation and server-side project seam. Keep\n   `businessPhoneNumber` in source-required E.164 form. Treat `groupId`,\n   `joinRequestId`, `requestId`, user/parent-user IDs, message IDs, and cursors as\n   opaque, case-sensitive strings; never parse examples, prefixes, suffixes, or\n   cursor contents. Preserve unknown response properties and enum/event values.\n2. Preserve request invariants exactly. Group create requires `subject`, applies\n   source length limits, and defaults omitted `joinApprovalMode` to\n   `auto_approve`. Settings updates require at least one of `subject` or\n   `description`. Participant removal supports at most eight entries, each with\n   exactly one of `user` or `fromUserId`; `userId` is a documented alias for\n   `fromUserId`. Join-request actions pass the opaque IDs returned by list and\n   retain per-item failures instead of treating a mixed result as atomic.\n3. Preserve cursor pagination for group and join-request lists: `limit` is 1 to\n   1024 with a default of 25, and `before`/`after` are opaque. Do not invent page\n   numbers, totals, stable ordering, or combine both cursor directions unless\n   the generated reference explicitly permits it. Parse the provider response as\n   `{data: [...], paging?: {before?, after?}}`; it is not the common\n   `offset/limit/length/items` Page envelope.\n4. For invite-link messages, require an approved template name, language code,\n   ordered body parameters, and one `type=group_id` parameter whose `group_id`\n   is the target group ID. The message goes to one user, not into the group.\n   Exactly one of `to` or `recipient` is required; if both exist, resolve and\n   validate `to` first and ignore `recipient` completely. Never fall back to\n   `recipient` when `to` is invalid. Hand accepted message state to Messages.\n5. Use placeholders and synthetic IDs/data in examples and tests. Use an\n   SDK-specific method only when the project contains a confirmed SDK artifact\n   and version; an `operationId` is not an SDK method. Keep `X-API-Key` injection\n   server-side through the Authentication handoff without reading a real key.\n6. Treat mutating timeouts or lost responses as ambiguous outcomes. Never\n   blindly replay a create, delete, update, participant action, invite-link\n   reset, join-request action, or message send. Any outbox, idempotency key,\n   retry budget, or reconciliation job is project architecture unless the\n   generated runtime reference says otherwise.\n\n## Accepted versus final state\n\nCreate, delete, settings update, and participant removal return\n`WhatsappGroupAsyncResponse`: HTTP `200`, `status=pending`, and `requestId` mean\nonly that YCloud accepted the asynchronous request. Preserve `requestId` for\ncorrelation with the separately confirmed group webhook event; do not label the\ngroup created/deleted/updated or participants removed at acceptance time.\n\nJoin-request approve/reject responses are itemized processing results; preserve\napproved/rejected IDs, failed items, and unknown errors. Invite-link reset returns\nthe new link synchronously but says nothing about message delivery. Invite-link\nmessage HTTP `200` returns `WhatsappMessage` and means message-request acceptance,\nnot delivery. Send its YCloud message ID and accepted state to\n`ycloud-whatsapp-messages`, which owns retrieve/status handling and the\naccepted-versus-final boundary. Webhook endpoint management and receiver\nreliability belong to `ycloud-webhook-endpoints`.\n\n## Mutation safeguards and tests\n\nDeletes, participant removals, join-request decisions, invite-link resets, and\nsettings changes can be disruptive or irreversible. Implement only local mock\nbehavior and no-network tests. For any future external workflow, stop before the\ncall, identify the exact opaque target IDs and impact, require explicit\noperation-specific confirmation, and treat an ambiguous result as unresolved.\n\nTests should cover every selected route and schema plus relevant negative cases:\npath asymmetry, E.164 validation, subject/description limits, join mode default,\ncursor bounds/opacity, empty or mixed join-request outcomes, partial failures,\nparticipant count and exactly-one identifier rules, unknown properties/statuses,\nprovider error/request-ID mapping, and accepted-versus-final correlation.\n\nFor invite-link messages, executable tests must cover neither recipient field,\neach field alone, both valid fields selecting `to`, valid `to` with malformed or\nwrong-typed `recipient` behaving exactly like `to` alone, invalid `to` with valid\n`recipient` rejecting without fallback, the required `group_id` parameter, and\nthe fact that acceptance is not delivery.\n\n## Outcome requirements\n\nReturn the matched operation IDs and exact method/paths, authority-labeled\ncontract facts, project-local artifacts or proposed seams, no-network test\nevidence, asynchronous correlation behavior, and explicit unknowns. Do not\nclaim an operation implemented because only a route label, button, sample JSON,\nor mock response exists; link each implemented row to its adapter/handler and\nbehavioral tests.\n\n### CANNOT\n\nList unsupported operations, missing project facts, source conflicts, unconfirmed\nSDK behavior, live credentials/customer data, real API calls, external\nmutations, automatic replay, final-state assumptions, and delivery claims.\nDo not move documented async `pending`/`requestId` behavior or known partial\njoin-request results into `CANNOT`.\n\n### Handoff\n\nSend ordinary group messages and invite-link-message post-acceptance tracking to\n`ycloud-whatsapp-messages` with the YCloud message ID kept separate from group,\nrequest, and project correlation IDs. Send Flow lifecycle to\n`ycloud-whatsapp-flows`, authentication storage to\n`ycloud-api-authentication`, and webhook endpoint/receiver work to\n`ycloud-webhook-endpoints`. Return to Architect with capability-row status,\nchanged or proposed artifacts, tests/results, accepted-versus-final evidence,\nunknowns, and outgoing handoffs.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}