{
  "id": "salon.chairside.capabilities@0.1.0",
  "capabilities": [
    {
      "id": "availability.search",
      "amenity": "booking",
      "role": "customer",
      "scope": "instance + client or authorized staff",
      "mutates": false,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "appointment.hold",
      "amenity": "booking",
      "role": "customer",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "appointment.confirm",
      "amenity": "booking",
      "role": "customer",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": true,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "appointment.reschedule",
      "amenity": "booking",
      "role": "customer",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": true,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "appointment.cancel",
      "amenity": "booking",
      "role": "customer",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": true,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "appointment.check-in",
      "amenity": "service-progress",
      "role": "staff",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "appointment.start",
      "amenity": "service-progress",
      "role": "staff",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "appointment.complete",
      "amenity": "service-progress",
      "role": "staff",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "waitlist.join",
      "amenity": "waitlist",
      "role": "customer",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "waitlist.accept",
      "amenity": "waitlist",
      "role": "staff",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "client.preferences.update",
      "amenity": "client-context",
      "role": "customer",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "checkout.quote",
      "amenity": "service-catalog",
      "role": "staff",
      "scope": "instance + client or authorized staff",
      "mutates": false,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "notification.retry",
      "amenity": "communications",
      "role": "staff",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "rebooking.propose",
      "amenity": "communications",
      "role": "staff",
      "scope": "instance + client or authorized staff",
      "mutates": true,
      "effect": "local-sandbox-only",
      "confirmationRequired": false,
      "requiredEnvelope": [
        "requestId",
        "idempotencyKey",
        "instanceId",
        "policyVersion",
        "actor"
      ],
      "schema": "Validated by public/runtime.js; unknown fields and identifiers rejected where relevant."
    },
    {
      "id": "review.submit",
      "amenity": "ratings",
      "role": "customer",
      "scope": "own completed sample appointment",
      "mutates": true,
      "effect": "local-sandbox-only",
      "productionGate": "OIDC authentication, visit eligibility, anti-abuse, review policy and moderation"
    }
  ]
}
