{
  "schema": "ci-xp-window-attributes-contract/v1",
  "version": "1.2.0",
  "status": "stable",
  "snapshot_schema": "ci-xp-window-attributes/v1",
  "scope": "Host-owned outer windows, desktop, taskbar and task buttons; no iframe role data or authorization changes",
  "projection_key": "window_attributes",
  "host_root_class": "xp-window",
  "attributes": {
    "session_role": {
      "optional": true,
      "scope": "verified-current-session",
      "dom_attribute": "data-xp-session-role",
      "class_prefix": "xp-window-session-role-",
      "known_values": [
        "guest",
        "customer",
        "developer",
        "admin"
      ],
      "source": "CI_Program_Catalog::role, backed by current effective AccountPolicy session role"
    },
    "app_type": {
      "optional": true,
      "scope": "registered-program",
      "dom_attribute": "data-xp-app-type",
      "class_prefix": "xp-window-app-type-",
      "known_values": [
        "url-app",
        "mcp-app",
        "weblink",
        "html-document",
        "wiki-page",
        "settings"
      ],
      "source": "CI_Program_Catalog::visible and non-conflicting catalog/explicit CI_Link_Classification key"
    },
    "app_role": {
      "optional": true,
      "dom_attribute": "data-xp-app-role",
      "class_prefix": "xp-window-app-role-",
      "scope": "verified-app-connection-per-window",
      "known_values": [
        "guest",
        "customer",
        "developer",
        "admin"
      ],
      "source": "Existing verified native session or resource-bound WP-Lab OAuth grant; never account maximum or implicit desktop fallback"
    }
  },
  "token_pattern": "^[a-z][a-z0-9-]{0,47}$",
  "program_id_pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,99}$",
  "compatibility": {
    "whole_extension_optional": true,
    "missing_values": "remove the corresponding old data attribute and class, never infer guest, admin or a generic app type",
    "unknown_safe_values": "retain as opaque display tokens, no default appearance or privileges",
    "unknown_fields": "ignore independently; do not reject known optional fields",
    "invalid_values": "omit the affected field only",
    "incompatible_schema": "clear this extension's fields; keep the window and unrelated classes unchanged",
    "new_features": "add independent optional fields in a minor revision of this schema",
    "merge_policy": "full snapshot replacement, never retain missing previous-session fields"
  },
  "presentation": {
    "css_required": false,
    "default_css": null,
    "default_colors": null,
    "default_badges": false,
    "role_type_precedence": null,
    "combined_rules": "normal skin-owned CSS cascade; both axes are independent",
    "legacy_category_loader": "not enabled and not reused"
  },
  "lifecycle": {
    "owner": "one adapter instance per desktop",
    "attach": "host passes its actual window element and program ID; type comes only from verified registry snapshot",
    "before_role_switch_or_logout": "invalidate synchronously before the asynchronous transition starts",
    "after_verified_state": "accept the current beginUpdate ticket and the freshly received snapshot",
    "on_verification_failure": "reject current ticket and clear stale styling hints",
    "on_owner_change": "invalidate or dispose before reusing a desktop",
    "on_window_close": "detach",
    "on_desktop_teardown": "dispose",
    "late_responses": "ignore tickets from an older generation, a superseded request or another desktop",
    "guest": "emit guest only after backend verification or verified guest bootstrap"
  },
  "security": {
    "grants_permissions": false,
    "accepts_app_messages": false,
    "accepts_url_role_parameters": false,
    "persists_session_metadata": false,
    "new_authentication_or_api_endpoint": false,
    "authorization": "unchanged server-side checks on every protected action"
  },
  "shell_surfaces": {
    "desktop": {
      "selector": ".xp-desktop",
      "role_attribute": "data-xp-session-role",
      "role_class_prefix": "xp-desktop-session-role-"
    },
    "taskbar": {
      "selector": ".xp-taskbar",
      "role_attribute": "data-xp-session-role",
      "role_class_prefix": "xp-taskbar-session-role-"
    },
    "task": {
      "selector": ".xp-task",
      "role_attribute": "data-xp-session-role",
      "role_class_prefix": "xp-task-session-role-",
      "app_type_attribute": "data-xp-app-type",
      "app_type_class_prefix": "xp-task-app-type-",
      "app_role_attribute": "data-xp-app-role",
      "app_role_class_prefix": "xp-task-app-role-"
    }
  },
  "skin_palette_policy": "Skin-owned; no automatic color or badge. New role/type skins opt in explicitly.",
  "shell_role_source": "Verified current WordPress session or explicit server-owned public guest renderer",
  "app_session": {
    "schema": "ci-xp-app-session/v1",
    "fields": [
      "connection",
      "state",
      "role",
      "source",
      "expires_at"
    ],
    "states": [
      "confirmed",
      "unknown"
    ],
    "maximum_age_seconds": 30,
    "unknown": "Neutral; never infer a role"
  }
}
