Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ThisIsMissEm/075efbb7233612444ce7be1c7781712d to your computer and use it in GitHub Desktop.

Select an option

Save ThisIsMissEm/075efbb7233612444ce7be1c7781712d to your computer and use it in GitHub Desktop.
Snapshot of swicg/activitypub-e2ee issue #56 (Maintaining ordering in the group conversation), captured 2026-05-09 — evidentiary backup for ActivityPub E2EE article (writings.thisismissem.social)
<!DOCTYPE html>
<html
lang="en"
data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
data-a11y-animated-images="system" data-a11y-link-underlines="true"
>
<head>
<meta charset="utf-8">
<link rel="dns-prefetch" href="https://github.githubassets.com">
<link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
<link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
<link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
<link rel="preconnect" href="https://github.githubassets.com" crossorigin>
<link rel="preconnect" href="https://avatars.githubusercontent.com">
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-2ff56e1b36116ee2.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-f7f95d7633592089.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-2d1fe43dbc9adf1f.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-d530ee188d165539.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-2ff56e1b36116ee2.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-f7f95d7633592089.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-e4bbc49fc7b82570.css" /><link data-color-theme="light_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind_high_contrast-cc3f126b45166b83.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-652ca611ea4e33fe.css" /><link data-color-theme="light_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia_high_contrast-9e82d635cb6c3f49.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-2d1fe43dbc9adf1f.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-d530ee188d165539.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-3ad0ec21150df75b.css" /><link data-color-theme="dark_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind_high_contrast-5691ff467f71a3f6.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-abee7710893cd168.css" /><link data-color-theme="dark_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia_high_contrast-eafcf6cd46158360.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-c7974682a1a84c8d.css" /><link data-color-theme="dark_dimmed_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed_high_contrast-f8dab3e04f94c501.css" />
<style type="text/css">
:root {
--tab-size-preference: 4;
}
pre, code {
tab-size: var(--tab-size-preference);
}
</style>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-7f694b60439d06c0.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-b48faa60c69660fa.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-81a5f61ff87ac6f0.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-f825c0edd7ad57f8.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-0751f482f5210958.css" />
<script type="application/json" id="client-env">{"locale":"en","featureFlags":["actions_custom_images_storage_billing_ui_visibility","actions_image_version_event","actions_workflow_language_service_allow_concurrency_queue","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","artifact_ui_v2","billing_discount_threshold_notification","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_automation_session_author","copilot_chat_attach_multiple_images","copilot_chat_category_rate_limit_messages","copilot_chat_clear_model_selection_for_default_change","copilot_chat_contextual_suggestions_updated","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_prettify_pasted_code","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_dotcom_chat_cache_repo_autocomplete_results","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_embedded_deferred_payload","copilot_immersive_embedded_draggable","copilot_immersive_embedded_header_button","copilot_immersive_embedded_implicit_references","copilot_immersive_embedded_skip_copilot_api_token_for_dotcom_context","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_filtering","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_session_status","copilot_mission_control_initial_data_spinner","copilot_mission_control_logs_incremental","copilot_mission_control_task_alive_updates","copilot_mission_control_tasks_repo_filter","copilot_org_policy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_upgrade_freeze","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","disable_preheating_for_issues","dotgithub_fork_warning","enterprise_managed_settings_for_copilot_clients","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_multi_assign_modal","issue_cca_task_side_panel","issue_cca_visualization","issue_cca_visualization_session_panel","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origin_optimization","project_picker_null_safety","prs_conversations_react","prs_css_anchor_positioning","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","security_center_artifact_filters_popover","selector_observer_stats","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","user_bypass_actors","viewscreen_sandbox","warn_inaccessible_attachments","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"}</script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/high-contrast-cookie-218067197ba03c91.js"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/wp-runtime-27323ee103414a20.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/fetch-utilities-3140609b5732710f.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/28839-7adfdde5afeb1a03.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/85924-ac5602ef611dc506.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/34646-4c7883eb242d5210.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/environment-8e8857b66d545299.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/runtime-helpers-cb4dfbc9d23f30be.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/2966-d68f2b4558d86113.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/96232-540ff5f81016a9ca.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/41013-647932573fc130af.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/51210-45dfb7dd106f6b96.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/81058-fc9ccbdd06141af8.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/81683-382ccc88e034ea1d.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/46740-5a373320e5ef9c01.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/82097-b1ab4d7cbdda0f4a.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/67466-79abcbf599986a00.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/github-elements-928ee121cbc88eff.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/element-registry-bffc865561a4d8b3.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/react-core-b2929a643e0ecc05.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/react-lib-1353f2cef82bcdc0.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/79039-69acf717ffc901a4.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/61110-073153e0413daf3a.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/2887-91b9c645d570616a.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/26533-f22c29ae5e9b1ed2.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/86483-c3a819d46503a3da.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/49521-3b553cd29062db6a.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/60481-24b13ea726837f7b.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/46287-3a1f3269a02b8060.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/33805-da9f821452a32f15.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/89627-40275597692dc855.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/79087-4f706db8aa2ec0fb.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/71410-874f65a04c129aeb.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/99328-a2c6b180d25cb160.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/behaviors-d9f0cee1f9e3eb0f.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-core.0c5a60be620dab14.module.css" />
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/4244-97fb660009234136.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/notifications-global-442a23b66c306470.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/primer-react-3ec1db98f7d5420b.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/octicons-react-60e727d7a1b6f52c.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/89602-a5f6b5137a0e6e26.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/23680-ebc1658f92b3666a.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/68751-830b37204cdf7847.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/47062-d1fa0b73fede728f.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/437-b61696b87744e40b.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/7463-30e02617b93e1c07.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/15272-0fca7ba11b03440f.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/41167-9d7086519f9ef4b7.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/32769-abc9916acf2cd4f1.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/73449-84f6039b29854149.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/70247-e8566061f7697493.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/25164-bca425945d2e8f99.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/28819-537db0fbb4d636b3.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/62094-a0c781f8be696b93.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/46903-da8c953d62c506b6.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/60939-74e045d52567f304.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/54206-7602bcfb3b252577.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/36505-9798da05fe2143ec.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/38304-3db3c8d9971760fe.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/40145-c24dfcf77e95e834.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/46148-264173ef30e2e838.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/40058-9247dfd4ab747b08.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/48860-cd0847f2fbc1a654.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/49417-79e7e54f64bfeb3f.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/63991-90c8c13c6389bc01.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/59852-cfe1350d4189acbb.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/66488-8d864de262e167ca.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/3624-db5771d166a8390b.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/17298-06d702eaf0eed47c.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/66231-67143789e9a4cfef.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/71001-fc3d5916447041f8.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/35644-78e198f2374e1303.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/15917-5ed92c63adef85bf.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/33684-bbaee6839ab84dd8.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/46040-b110177b08ec9e86.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/73024-6967426a72b29bae.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/49029-eaa2781f5deee0c7.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/96755-d09718cd443d357b.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/86436-390bd6a2b37d3440.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/24787-78351bb0a4a4df0d.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/4916-e48946e12dfe055d.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/62874-c609668083a55564.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/44880-2ffa90c8c95b757c.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/97685-9b8528d791d60e5d.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/29139-70f8ebf3a87e9e50.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/71482-58497068f8214f70.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/56074-a7337aab3acb6ef0.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/6174-12bbf69c176564b4.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/77440-a0496f63c5d86021.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/10764-ab2c4a558384e486.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/12120-49691fd93fb3a7ba.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/41371-5c7b2bf716c4aa73.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/15151-d2f36fb3dcbc55b4.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/64910-16c68a186a1bd171.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/38184-ba2fd6ec1ca34a6e.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/56790-cbc9980ebd3cb824.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/42829-b999f43f743cdd93.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/90620-fe70f907b5424fb0.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/80070-9242f5ac18943dd1.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/15716-853ef2cab1050baf.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/11722-2341f59da989c7fb.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/70882-8f89e3fad6bb6a56.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/94465-5f21e39b3c6de9c9.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/24307-658547e6d530187a.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/issues-react-7341bc44a57a11a8.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.48c74afb1f96b5a7.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/15917.02d1947a0156c7de.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/6174.d7261f894d19b4b2.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/42829.dfceba0b010d2ea4.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/15716.0e47438780711235.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/70882.3bdf9fffcc1593c7.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/24307.d73238b9dd57a236.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/issues-react.7c887d8580f5ab1a.module.css" />
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/84534-e011301c1768a3eb.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/84784-3af5ea8ea4b9246c.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/17423-d06ec7cad1c7da3f.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/notifications-subscriptions-menu-6b4f76a0253993b2.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/notifications-subscriptions-menu.4012128102e2fbca.module.css" />
<title>Maintaining ordering in the group conversation · Issue #56 · swicg/activitypub-e2ee · GitHub</title>
<meta name="route-pattern" content="/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)" data-turbo-transient>
<meta name="route-controller" content="voltron_issues_fragments" data-turbo-transient>
<meta name="route-action" content="issue_layout" data-turbo-transient>
<meta name="fetch-nonce" content="v2:339763b5-4c4c-e4dc-589d-2beaf6772f7e">
<meta name="current-catalog-service-hash" content="81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114">
<meta name="request-id" content="D8EC:11CD58:25C1A68:1CEDCD9:69FE5E61" data-pjax-transient="true"/><meta name="html-safe-nonce" content="c53d50cc6784cdc4886afa886756c8db69533174ed06e6592ebfcea9f75890f5" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJEOEVDOjExQ0Q1ODoyNUMxQTY4OjFDRURDRDk6NjlGRTVFNjEiLCJ2aXNpdG9yX2lkIjoiNzk2MzExMzUzMzE1ODA4ODI4OSIsInJlZ2lvbl9lZGdlIjoiZnJhIiwicmVnaW9uX3JlbmRlciI6ImZyYSJ9" data-pjax-transient="true"/><meta name="visitor-hmac" content="c44319259dc802522078abe8b788ec58d4f904bfe07bbafb469248869ec72408" data-pjax-transient="true"/>
<meta name="hovercard-subject-tag" content="issue:3793337837" data-turbo-transient>
<meta name="github-keyboard-shortcuts" content="repository,issues,copilot" data-turbo-transient="true" />
<meta name="selected-link" value="repo_issues" data-turbo-transient>
<link rel="assets" href="https://github.githubassets.com/">
<meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">
<meta name="octolytics-url" content="https://collector.github.com/github/collect" />
<meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/voltron/issues_fragments/issue_layout" data-turbo-transient="true" />
<meta name="user-login" content="">
<meta name="viewport" content="width=device-width">
<meta name="description" content="Ordering is very important in MLS. We need to have a way to have an official ordering.">
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
<link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
<meta property="fb:app_id" content="1401488693436528">
<meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/swicg/activitypub-e2ee/56/issue_layout" />
<meta name="twitter:image" content="https://opengraph.githubassets.com/b37ef6c37079c490e347916761b95f88d7eedb0d2ef0ec4e78be3daab1560457/swicg/activitypub-e2ee/issues/56" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="Maintaining ordering in the group conversation · Issue #56 · swicg/activitypub-e2ee" /><meta name="twitter:description" content="Ordering is very important in MLS. We need to have a way to have an official ordering." />
<meta property="og:image" content="https://opengraph.githubassets.com/b37ef6c37079c490e347916761b95f88d7eedb0d2ef0ec4e78be3daab1560457/swicg/activitypub-e2ee/issues/56" /><meta property="og:image:alt" content="Ordering is very important in MLS. We need to have a way to have an official ordering." /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="Maintaining ordering in the group conversation · Issue #56 · swicg/activitypub-e2ee" /><meta property="og:url" content="https://github.com/swicg/activitypub-e2ee/issues/56" /><meta property="og:description" content="Ordering is very important in MLS. We need to have a way to have an official ordering." /><meta property="og:author:username" content="evanp" />
<meta name="hostname" content="github.com">
<meta name="expected-hostname" content="github.com">
<meta http-equiv="x-pjax-version" content="f6600c386c6230025bba70abac19fa46af0194c2975e93a04b0fddbe58a27a11" data-turbo-track="reload">
<meta http-equiv="x-pjax-csp-version" content="568c098497d98702bac1642a2a853732a047a6ced28eabd3e15d50041a890235" data-turbo-track="reload">
<meta http-equiv="x-pjax-css-version" content="a1b38a3acd18ce9dc43e496efc2c542ae56a9d3079910fa81d6ad24488c00dc4" data-turbo-track="reload">
<meta http-equiv="x-pjax-js-version" content="bb44b328e2d1b17a59b75c8fb3f3de7d38c14dd523a05f47952d6def67b7f22f" data-turbo-track="reload">
<meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">
<meta name="voltron-timing" value="655">
<script type="application/ld+json">{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Maintaining ordering in the group conversation","articleBody":"Ordering is very important in MLS. We need to have a way to have an official ordering.","author":{"url":"https://github.com/evanp","@type":"Person","name":"evanp"},"datePublished":"2026-01-08T15:26:08.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":7},"url":"https://github.com/56/activitypub-e2ee/issues/56"}</script>
<meta name="go-import" content="github.com/swicg/activitypub-e2ee git https://github.com/swicg/activitypub-e2ee.git">
<meta name="octolytics-dimension-user_id" content="23560971" /><meta name="octolytics-dimension-user_login" content="swicg" /><meta name="octolytics-dimension-repository_id" content="804531295" /><meta name="octolytics-dimension-repository_nwo" content="swicg/activitypub-e2ee" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="804531295" /><meta name="octolytics-dimension-repository_network_root_nwo" content="swicg/activitypub-e2ee" />
<link rel="canonical" href="https://github.com/swicg/activitypub-e2ee/issues/56" data-turbo-transient>
<meta name="turbo-body-classes" content="logged-out env-production page-responsive">
<meta name="disable-turbo" content="false">
<meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
<meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
<meta name="release" content="399e77c0dae3558588eaf07d67f4db9c30ebe7a9">
<meta name="ui-target" content="full">
<link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000">
<link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
<link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon">
<meta name="theme-color" content="#1e2327">
<meta name="color-scheme" content="light dark" />
<link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">
</head>
<body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
<div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
<div id="__primerPortalRoot__" style="z-index: 1000; position: absolute; width: 100%;" data-turbo-permanent></div>
<div class="position-relative header-wrapper js-header-wrapper ">
<a href="#start-of-content" data-skip-target-assigned="false" class="px-2 tmp-py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a>
<span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full">
<span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span>
</span>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.670668115736ecbc.module.css" />
<react-partial
partial-name="keyboard-shortcuts-dialog"
data-ssr="false"
data-attempted-ssr="false"
data-react-profiling="false"
>
<script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script>
<div data-target="react-partial.reactRoot"></div>
</react-partial>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/46752-7bd8967216f7ea42.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/90350-89ca7e5359af8f77.js" defer="defer"></script>
<script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/sessions-e0da6ce03532723c.js" defer="defer"></script>
<style>
/* Override primer focus outline color for marketing header dropdown links for better contrast */
[data-color-mode="light"] .HeaderMenu-dropdown-link:focus-visible,
[data-color-mode="light"] .HeaderMenu-trailing-link a:focus-visible {
outline-color: var(--color-accent-fg);
}
</style>
<header class="HeaderMktg header-logged-out js-details-container js-header Details f4 tmp-py-3" role="banner" data-is-top="true" data-color-mode=auto data-light-theme=light data-dark-theme=dark>
<h2 class="sr-only">Navigation Menu</h2>
<button type="button" class="HeaderMktg-backdrop d-lg-none border-0 position-fixed top-0 left-0 width-full height-full js-details-target" aria-label="Toggle navigation">
<span class="d-none">Toggle navigation</span>
</button>
<div class="d-flex flex-column flex-lg-row flex-items-center tmp-px-3 tmp-px-md-4 tmp-px-lg-5 height-full position-relative z-1">
<div class="d-flex flex-justify-between flex-items-center width-full width-lg-auto">
<div class="flex-1">
<button aria-label="Toggle navigation" aria-expanded="false" type="button" data-view-component="true" class="js-details-target js-nav-padding-recalculate js-header-menu-toggle Button--link Button--medium Button d-lg-none color-fg-inherit p-1 tmp-p-1"> <span class="Button-content">
<span class="Button-label"><div class="HeaderMenu-toggle-bar rounded my-1"></div>
<div class="HeaderMenu-toggle-bar rounded my-1"></div>
<div class="HeaderMenu-toggle-bar rounded my-1"></div></span>
</span>
</button>
</div>
<a class="tmp-mr-lg-3 color-fg-inherit flex-order-2 js-prevent-focus-on-mobile-nav"
href="/"
aria-label="Homepage"
data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to go to homepage&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Logomark;ref_loc:Header&quot;}">
<svg height="32" aria-hidden="true" data-component="Octicon" viewBox="0 0 24 24" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github">
<path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path>
</svg>
</a>
<div class="d-flex flex-1 flex-order-2 text-right d-lg-none gap-2 flex-justify-end">
<a
href="/login?return_to=https%3A%2F%2Fgithub.com%2Fswicg%2Factivitypub-e2ee%2Fissues%2F56"
class="HeaderMenu-link HeaderMenu-button d-inline-flex f5 no-underline border color-border-default rounded-2 px-2 py-1 color-fg-inherit js-prevent-focus-on-mobile-nav"
data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/swicg/activitypub-e2ee/issues/56&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="9a5bd50f43bb22dd8261e33fac3f8c78f18622cfbdf5d1f589b851fe9a460f98"
data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to Sign in&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Sign in;ref_loc:Header&quot;}"
>
Sign in
</a>
<div class="AppHeader-appearanceSettings">
<react-partial-anchor>
<button data-target="react-partial-anchor.anchor" id="icon-button-a9b06ee8-943c-4700-8437-e959a7d5c6b3" aria-labelledby="tooltip-1e40fba2-3641-4d42-b08f-9c2a56734e18" type="button" disabled="disabled" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium AppHeader-button HeaderMenu-link border cursor-wait"> <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-sliders Button-visual">
<path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path>
</svg>
</button><tool-tip id="tooltip-1e40fba2-3641-4d42-b08f-9c2a56734e18" for="icon-button-a9b06ee8-943c-4700-8437-e959a7d5c6b3" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Appearance settings</tool-tip>
<template data-target="react-partial-anchor.template">
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/appearance-settings.3690bbff0a0fd071.module.css" />
<react-partial
partial-name="appearance-settings"
data-ssr="false"
data-attempted-ssr="false"
data-react-profiling="false"
>
<script type="application/json" data-target="react-partial.embeddedData">{"props":{}}</script>
<div data-target="react-partial.reactRoot"></div>
</react-partial>
</template>
</react-partial-anchor>
</div>
</div>
</div>
<div class="HeaderMenu js-header-menu height-fit position-lg-relative d-lg-flex flex-column flex-auto top-0">
<div class="HeaderMenu-wrapper d-flex flex-column flex-self-start flex-lg-row flex-auto rounded rounded-lg-0">
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/marketing-navigation.9c460dc5436e5da3.module.css" />
<react-partial
partial-name="marketing-navigation"
data-ssr="true"
data-attempted-ssr="true"
data-react-profiling="false"
>
<script type="application/json" data-target="react-partial.embeddedData">{"props":{"should_use_dotcom_links":true}}</script>
<div data-target="react-partial.reactRoot"><nav class="MarketingNavigation-module__nav__W0KYY" aria-label="Global"><ul class="MarketingNavigation-module__list__tFbMb"><li><div class="NavDropdown-module__container__l2YeI js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button__PEHWX js-details-target" aria-expanded="false">Platform<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_5hb_">AI CODE CREATION</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5hb_"><li><a href="https://github.com/features/copilot" data-analytics-event="{&quot;action&quot;:&quot;github_copilot&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path></svg><span class="NavLink-module__title__Q7t0p">GitHub Copilot</span><span class="NavLink-module__subtitle__X4gkW">Write better code with AI</span></div></a></li><li><a href="https://github.com/features/spark" data-analytics-event="{&quot;action&quot;:&quot;github_spark&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_spark_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sparkle-fill NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M11.296 1.924c.24-.656 1.168-.656 1.408 0l.717 1.958a11.25 11.25 0 0 0 6.697 6.697l1.958.717c.657.24.657 1.168 0 1.408l-1.958.717a11.25 11.25 0 0 0-6.697 6.697l-.717 1.958c-.24.657-1.168.657-1.408 0l-.717-1.958a11.25 11.25 0 0 0-6.697-6.697l-1.958-.717c-.656-.24-.656-1.168 0-1.408l1.958-.717a11.25 11.25 0 0 0 6.697-6.697l.717-1.958Z"></path></svg><span class="NavLink-module__title__Q7t0p">GitHub Spark</span><span class="NavLink-module__subtitle__X4gkW">Build and deploy intelligent apps</span></div></a></li><li><a href="https://github.com/features/models" data-analytics-event="{&quot;action&quot;:&quot;github_models&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_models_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-ai-model NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M19.375 8.5a3.25 3.25 0 1 1-3.163 4h-3a3.252 3.252 0 0 1-4.443 2.509L7.214 17.76a3.25 3.25 0 1 1-1.342-.674l1.672-2.957A3.238 3.238 0 0 1 6.75 12c0-.907.371-1.727.97-2.316L6.117 6.846A3.253 3.253 0 0 1 1.875 3.75a3.25 3.25 0 1 1 5.526 2.32l1.603 2.836A3.25 3.25 0 0 1 13.093 11h3.119a3.252 3.252 0 0 1 3.163-2.5ZM10 10.25a1.75 1.75 0 1 0-.001 3.499A1.75 1.75 0 0 0 10 10.25ZM5.125 2a1.75 1.75 0 1 0 0 3.5 1.75 1.75 0 0 0 0-3.5Zm12.5 9.75a1.75 1.75 0 1 0 3.5 0 1.75 1.75 0 0 0-3.5 0Zm-14.25 8.5a1.75 1.75 0 1 0 3.501-.001 1.75 1.75 0 0 0-3.501.001Z"></path></svg><span class="NavLink-module__title__Q7t0p">GitHub Models</span><span class="NavLink-module__subtitle__X4gkW">Manage and compare prompts</span></div></a></li><li><a href="https://github.com/mcp" data-analytics-event="{&quot;action&quot;:&quot;mcp_registry&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;mcp_registry_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.795 1.694a4.287 4.287 0 0 1 6.061 0 4.28 4.28 0 0 1 1.181 3.819 4.282 4.282 0 0 1 3.819 1.181 4.287 4.287 0 0 1 0 6.061l-6.793 6.793a.249.249 0 0 0 0 .353l2.617 2.618a.75.75 0 1 1-1.061 1.061l-2.617-2.618a1.75 1.75 0 0 1 0-2.475l6.793-6.793a2.785 2.785 0 1 0-3.939-3.939l-5.9 5.9a.734.734 0 0 1-.249.165.749.749 0 0 1-.812-1.225l5.9-5.901a2.785 2.785 0 1 0-3.939-3.939L2.931 10.68A.75.75 0 1 1 1.87 9.619l7.925-7.925Z"></path><path d="M12.42 4.069a.752.752 0 0 1 1.061 0 .752.752 0 0 1 0 1.061L7.33 11.28a2.788 2.788 0 0 0 0 3.94 2.788 2.788 0 0 0 3.94 0l6.15-6.151a.752.752 0 0 1 1.061 0 .752.752 0 0 1 0 1.061l-6.151 6.15a4.285 4.285 0 1 1-6.06-6.06l6.15-6.151Z"></path></svg><span class="NavLink-module__title__Q7t0p">MCP Registry<sup class="NavLink-module__label__bil7n">New</sup></span><span class="NavLink-module__subtitle__X4gkW">Integrate external tools</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_9hb_">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9hb_"><li><a href="https://github.com/features/actions" data-analytics-event="{&quot;action&quot;:&quot;actions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;actions_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1 3a2 2 0 0 1 2-2h6.5a2 2 0 0 1 2 2v6.5a2 2 0 0 1-2 2H7v4.063C7 16.355 7.644 17 8.438 17H12.5v-2.5a2 2 0 0 1 2-2H21a2 2 0 0 1 2 2V21a2 2 0 0 1-2 2h-6.5a2 2 0 0 1-2-2v-2.5H8.437A2.939 2.939 0 0 1 5.5 15.562V11.5H3a2 2 0 0 1-2-2Zm2-.5a.5.5 0 0 0-.5.5v6.5a.5.5 0 0 0 .5.5h6.5a.5.5 0 0 0 .5-.5V3a.5.5 0 0 0-.5-.5ZM14.5 14a.5.5 0 0 0-.5.5V21a.5.5 0 0 0 .5.5H21a.5.5 0 0 0 .5-.5v-6.5a.5.5 0 0 0-.5-.5Z"></path></svg><span class="NavLink-module__title__Q7t0p">Actions</span><span class="NavLink-module__subtitle__X4gkW">Automate any workflow</span></div></a></li><li><a href="https://github.com/features/codespaces" data-analytics-event="{&quot;action&quot;:&quot;codespaces&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;codespaces_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.5 3.75C3.5 2.784 4.284 2 5.25 2h13.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 18.75 13H5.25a1.75 1.75 0 0 1-1.75-1.75Zm-2 12c0-.966.784-1.75 1.75-1.75h17.5c.966 0 1.75.784 1.75 1.75v4a1.75 1.75 0 0 1-1.75 1.75H3.25a1.75 1.75 0 0 1-1.75-1.75ZM5.25 3.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h13.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Zm-2 12a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h17.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25Z"></path><path d="M10 17.75a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path></svg><span class="NavLink-module__title__Q7t0p">Codespaces</span><span class="NavLink-module__subtitle__X4gkW">Instant dev environments</span></div></a></li><li><a href="https://github.com/features/issues" data-analytics-event="{&quot;action&quot;:&quot;issues&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;issues_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Zm9.5 2a2 2 0 1 1-.001-3.999A2 2 0 0 1 12 14Z"></path></svg><span class="NavLink-module__title__Q7t0p">Issues</span><span class="NavLink-module__subtitle__X4gkW">Plan and track work</span></div></a></li><li><a href="https://github.com/features/code-review" data-analytics-event="{&quot;action&quot;:&quot;code_review&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_review_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15.22 4.97a.75.75 0 0 1 1.06 0l6.5 6.5a.75.75 0 0 1 0 1.06l-6.5 6.5a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L21.19 12l-5.97-5.97a.75.75 0 0 1 0-1.06Zm-6.44 0a.75.75 0 0 1 0 1.06L2.81 12l5.97 5.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-6.5-6.5a.75.75 0 0 1 0-1.06l6.5-6.5a.75.75 0 0 1 1.06 0Z"></path></svg><span class="NavLink-module__title__Q7t0p">Code Review</span><span class="NavLink-module__subtitle__X4gkW">Manage code changes</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_dhb_">APPLICATION SECURITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dhb_"><li><a href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path></svg><span class="NavLink-module__title__Q7t0p">GitHub Advanced Security</span><span class="NavLink-module__subtitle__X4gkW">Find and fix vulnerabilities</span></div></a></li><li><a href="https://github.com/security/advanced-security/code-security" data-analytics-event="{&quot;action&quot;:&quot;code_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_security_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.3 8.24a.75.75 0 0 1-.04 1.06L7.352 12l2.908 2.7a.75.75 0 1 1-1.02 1.1l-3.5-3.25a.75.75 0 0 1 0-1.1l3.5-3.25a.75.75 0 0 1 1.06.04Zm3.44 1.06a.75.75 0 1 1 1.02-1.1l3.5 3.25a.75.75 0 0 1 0 1.1l-3.5 3.25a.75.75 0 1 1-1.02-1.1l2.908-2.7-2.908-2.7Z"></path><path d="M2 3.75C2 2.784 2.784 2 3.75 2h16.5c.966 0 1.75.784 1.75 1.75v16.5A1.75 1.75 0 0 1 20.25 22H3.75A1.75 1.75 0 0 1 2 20.25Zm1.75-.25a.25.25 0 0 0-.25.25v16.5c0 .138.112.25.25.25h16.5a.25.25 0 0 0 .25-.25V3.75a.25.25 0 0 0-.25-.25Z"></path></svg><span class="NavLink-module__title__Q7t0p">Code security</span><span class="NavLink-module__subtitle__X4gkW">Secure your code as you build</span></div></a></li><li><a href="https://github.com/security/advanced-security/secret-protection" data-analytics-event="{&quot;action&quot;:&quot;secret_protection&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;secret_protection_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6 9V7.25C6 3.845 8.503 1 12 1s6 2.845 6 6.25V9h.5a2.5 2.5 0 0 1 2.5 2.5v8a2.5 2.5 0 0 1-2.5 2.5h-13A2.5 2.5 0 0 1 3 19.5v-8A2.5 2.5 0 0 1 5.5 9Zm-1.5 2.5v8a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-13a1 1 0 0 0-1 1Zm3-4.25V9h9V7.25c0-2.67-1.922-4.75-4.5-4.75-2.578 0-4.5 2.08-4.5 4.75Z"></path></svg><span class="NavLink-module__title__Q7t0p">Secret protection</span><span class="NavLink-module__subtitle__X4gkW">Stop leaks before they start</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ NavGroup-module__hasSeparator__FnMrN"><span class="NavGroup-module__title__Wzxz2" id="_R_hhb_">EXPLORE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_hhb_"><li><a href="https://github.com/why-github" data-analytics-event="{&quot;action&quot;:&quot;why_github&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;why_github_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Why GitHub</span></a></li><li><a href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">Documentation</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.blog" data-analytics-event="{&quot;action&quot;:&quot;blog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;blog_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">Blog</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.blog/changelog" data-analytics-event="{&quot;action&quot;:&quot;changelog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;changelog_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">Changelog</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.com/marketplace" data-analytics-event="{&quot;action&quot;:&quot;marketplace&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;marketplace_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a href="https://github.com/features" data-analytics-event="{&quot;action&quot;:&quot;view_all_features&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_features_link_platform_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">View all features</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon__amekg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button__PEHWX js-details-target" aria-expanded="false">Solutions<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_5ib_">BY COMPANY SIZE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5ib_"><li><a href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprises&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Enterprises</span></a></li><li><a href="https://github.com/team" data-analytics-event="{&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Small and medium teams</span></a></li><li><a href="https://github.com/enterprise/startups" data-analytics-event="{&quot;action&quot;:&quot;startups&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Startups</span></a></li><li><a href="https://github.com/solutions/industry/nonprofits" data-analytics-event="{&quot;action&quot;:&quot;nonprofits&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_9ib_">BY USE CASE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9ib_"><li><a href="https://github.com/solutions/use-case/app-modernization" data-analytics-event="{&quot;action&quot;:&quot;app_modernization&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;app_modernization_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">App Modernization</span></a></li><li><a href="https://github.com/solutions/use-case/devsecops" data-analytics-event="{&quot;action&quot;:&quot;devsecops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">DevSecOps</span></a></li><li><a href="https://github.com/solutions/use-case/devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">DevOps</span></a></li><li><a href="https://github.com/solutions/use-case/ci-cd" data-analytics-event="{&quot;action&quot;:&quot;ci/cd&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ci/cd_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">CI/CD</span></a></li><li><a href="https://github.com/solutions/use-case" data-analytics-event="{&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">View all use cases</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon__amekg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_dib_">BY INDUSTRY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dib_"><li><a href="https://github.com/solutions/industry/healthcare" data-analytics-event="{&quot;action&quot;:&quot;healthcare&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Healthcare</span></a></li><li><a href="https://github.com/solutions/industry/financial-services" data-analytics-event="{&quot;action&quot;:&quot;financial_services&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Financial services</span></a></li><li><a href="https://github.com/solutions/industry/manufacturing" data-analytics-event="{&quot;action&quot;:&quot;manufacturing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Manufacturing</span></a></li><li><a href="https://github.com/solutions/industry/government" data-analytics-event="{&quot;action&quot;:&quot;government&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Government</span></a></li><li><a href="https://github.com/solutions/industry" data-analytics-event="{&quot;action&quot;:&quot;view_all_industries&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">View all industries</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon__amekg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a href="https://github.com/solutions" data-analytics-event="{&quot;action&quot;:&quot;view_all_solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_solutions_link_solutions_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">View all solutions</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon__amekg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button__PEHWX js-details-target" aria-expanded="false">Resources<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_5jb_">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5jb_"><li><a href="https://github.com/resources/articles?topic=ai" data-analytics-event="{&quot;action&quot;:&quot;ai&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">AI</span></a></li><li><a href="https://github.com/resources/articles?topic=software-development" data-analytics-event="{&quot;action&quot;:&quot;software_development&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Software Development</span></a></li><li><a href="https://github.com/resources/articles?topic=devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">DevOps</span></a></li><li><a href="https://github.com/resources/articles?topic=security" data-analytics-event="{&quot;action&quot;:&quot;security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Security</span></a></li><li><a href="https://github.com/resources/articles" data-analytics-event="{&quot;action&quot;:&quot;view_all_topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_topics_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">View all topics</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon__amekg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_9jb_">EXPLORE BY TYPE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9jb_"><li><a href="https://github.com/customer-stories" data-analytics-event="{&quot;action&quot;:&quot;customer_stories&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Customer stories</span></a></li><li><a href="https://github.com/resources/events" data-analytics-event="{&quot;action&quot;:&quot;events__webinars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;events__webinars_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Events &amp; webinars</span></a></li><li><a href="https://github.com/resources/whitepapers" data-analytics-event="{&quot;action&quot;:&quot;ebooks__reports&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ebooks__reports_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Ebooks &amp; reports</span></a></li><li><a href="https://github.com/solutions/executive-insights" data-analytics-event="{&quot;action&quot;:&quot;business_insights&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;business_insights_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Business insights</span></a></li><li><a href="https://skills.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_skills&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_skills_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">GitHub Skills</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_djb_">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_djb_"><li><a href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">Documentation</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://support.github.com" data-analytics-event="{&quot;action&quot;:&quot;customer_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_support_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">Customer support</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.com/orgs/community/discussions" data-analytics-event="{&quot;action&quot;:&quot;community_forum&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;community_forum_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Community forum</span></a></li><li><a href="https://github.com/trust-center" data-analytics-event="{&quot;action&quot;:&quot;trust_center&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trust_center_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Trust center</span></a></li><li><a href="https://github.com/partners" data-analytics-event="{&quot;action&quot;:&quot;partners&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Partners</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a href="https://github.com/resources" data-analytics-event="{&quot;action&quot;:&quot;view_all_resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_resources_link_resources_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">View all resources</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavLink-module__arrowIcon__amekg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button__PEHWX js-details-target" aria-expanded="false">Open Source<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_5kb_">COMMUNITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5kb_"><li><a href="https://github.com/sponsors" data-analytics-event="{&quot;action&quot;:&quot;github_sponsors&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M16.004 1.25C18.311 1.25 20 3.128 20 5.75c0 2.292-1.23 4.464-3.295 6.485-.481.47-.98.909-1.482 1.31l.265 1.32 1.375 7.5a.75.75 0 0 1-.982.844l-3.512-1.207a.75.75 0 0 0-.488 0L8.37 23.209a.75.75 0 0 1-.982-.844l1.378-7.512.261-1.309c-.5-.4-1-.838-1.481-1.31C5.479 10.215 4.25 8.043 4.25 5.75c0-2.622 1.689-4.5 3.996-4.5 1.55 0 2.947.752 3.832 1.967l.047.067.047-.067a4.726 4.726 0 0 1 3.612-1.962l.22-.005ZM13.89 14.531c-.418.285-.828.542-1.218.77l-.18.103a.75.75 0 0 1-.734 0l-.071-.04-.46-.272c-.282-.173-.573-.36-.868-.562l-.121.605-1.145 6.239 2.3-.79a2.248 2.248 0 0 1 1.284-.054l.18.053 2.299.79-1.141-6.226-.125-.616ZM16.004 2.75c-1.464 0-2.731.983-3.159 2.459-.209.721-1.231.721-1.44 0-.428-1.476-1.695-2.459-3.16-2.459-1.44 0-2.495 1.173-2.495 3 0 1.811 1.039 3.647 2.844 5.412a19.624 19.624 0 0 0 3.734 2.84l-.019-.011-.184-.111.147-.088a19.81 19.81 0 0 0 3.015-2.278l.37-.352C17.46 9.397 18.5 7.561 18.5 5.75c0-1.827-1.055-3-2.496-3Z"></path></svg><span class="NavLink-module__title__Q7t0p">GitHub Sponsors</span><span class="NavLink-module__subtitle__X4gkW">Fund open source developers</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_9kb_">PROGRAMS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9kb_"><li><a href="https://securitylab.github.com" data-analytics-event="{&quot;action&quot;:&quot;security_lab&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_lab_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">Security Lab</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://maintainers.github.com" data-analytics-event="{&quot;action&quot;:&quot;maintainer_community&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;maintainer_community_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">Maintainer Community</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://github.com/accelerator" data-analytics-event="{&quot;action&quot;:&quot;accelerator&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;accelerator_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Accelerator</span></a></li><li><a href="https://stars.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_stars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_stars_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">GitHub Stars</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a href="https://archiveprogram.github.com" data-analytics-event="{&quot;action&quot;:&quot;archive_program&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;archive_program_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4" target="_blank" rel="noreferrer"><span class="NavLink-module__title__Q7t0p">Archive Program</span><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-link-external NavLink-module__externalIcon__eWIry" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_dkb_">REPOSITORIES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dkb_"><li><a href="https://github.com/topics" data-analytics-event="{&quot;action&quot;:&quot;topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Topics</span></a></li><li><a href="https://github.com/trending" data-analytics-event="{&quot;action&quot;:&quot;trending&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Trending</span></a></li><li><a href="https://github.com/collections" data-analytics-event="{&quot;action&quot;:&quot;collections&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}" class="NavLink-module__link__EG3d4"><span class="NavLink-module__title__Q7t0p">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container__l2YeI js-details-container js-header-menu-item"><button type="button" class="NavDropdown-module__button__PEHWX js-details-target" aria-expanded="false">Enterprise<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-chevron-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path></svg></button><div class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_5lb_">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5lb_"><li><a href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M11.063 1.456a1.749 1.749 0 0 1 1.874 0l8.383 5.316a1.751 1.751 0 0 1 0 2.956l-8.383 5.316a1.749 1.749 0 0 1-1.874 0L2.68 9.728a1.751 1.751 0 0 1 0-2.956Zm1.071 1.267a.25.25 0 0 0-.268 0L3.483 8.039a.25.25 0 0 0 0 .422l8.383 5.316a.25.25 0 0 0 .268 0l8.383-5.316a.25.25 0 0 0 0-.422Z"></path><path d="M1.867 12.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path><path d="M1.867 16.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path></svg><span class="NavLink-module__title__Q7t0p">Enterprise platform</span><span class="NavLink-module__subtitle__X4gkW">AI-powered developer platform</span></div></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="NavGroup-module__title__Wzxz2" id="_R_9lb_">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9lb_"><li><a href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_enterprise_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path></svg><span class="NavLink-module__title__Q7t0p">GitHub Advanced Security</span><span class="NavLink-module__subtitle__X4gkW">Enterprise-grade security features</span></div></a></li><li><a href="https://github.com/features/copilot/copilot-business" data-analytics-event="{&quot;action&quot;:&quot;copilot_for_business&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;copilot_for_business_link_enterprise_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path></svg><span class="NavLink-module__title__Q7t0p">Copilot for Business</span><span class="NavLink-module__subtitle__X4gkW">Enterprise-grade AI features</span></div></a></li><li><a href="https://github.com/premium-support" data-analytics-event="{&quot;action&quot;:&quot;premium_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}" class="NavLink-module__link__EG3d4"><div class="NavLink-module__text__XvpLQ"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon__ltGNM" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path></svg><span class="NavLink-module__title__Q7t0p">Premium Support</span><span class="NavLink-module__subtitle__X4gkW">Enterprise-grade 24/7 support</span></div></a></li></ul></div></li></ul></div></div></li><li><a href="https://github.com/pricing" data-analytics-event="{&quot;action&quot;:&quot;pricing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;pricing&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;pricing_link_pricing_navbar&quot;}" class="NavLink-module__link__EG3d4 MarketingNavigation-module__navLink__hUomM"><span class="NavLink-module__title__Q7t0p">Pricing</span></a></li></ul></nav><script type="application/json" id="__PRIMER_DATA__R_0___">{"resolvedServerColorMode":"day"}</script></div>
</react-partial>
<div class="d-flex flex-column flex-lg-row width-full flex-justify-end flex-lg-items-center text-center tmp-mt-3 tmp-mt-lg-0 text-lg-left tmp-ml-lg-3">
<qbsearch-input class="search-input" data-scope="repo:swicg/activitypub-e2ee" data-custom-scopes-path="/search/custom_scopes" data-delete-custom-scopes-csrf="A4aNotgv0S3X1N5NZBHjYqh5xfYnw9nIEySWRSqKzeolo-NjZcbE7bjKoHWM2ldoSqsMl6d8Ses1gq4omq2q9g" data-max-custom-scopes="10" data-header-redesign-enabled="false" data-initial-value="" data-blackbird-suggestions-path="/search/suggestions" data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations" data-current-repository="swicg/activitypub-e2ee" data-current-org="swicg" data-current-owner="" data-logged-in="false" data-copilot-chat-enabled="false" data-nl-search-enabled="false" data-retain-scroll-position="true">
<div
class="search-input-container search-with-dialog position-relative d-flex flex-row flex-items-center tmp-mr-4 rounded"
data-action="click:qbsearch-input#searchInputContainerClicked"
>
<button
type="button"
class="header-search-button placeholder input-button form-control d-flex flex-1 flex-self-stretch flex-items-center no-wrap width-full py-0 pl-2 pr-0 text-left border-0 box-shadow-none"
data-target="qbsearch-input.inputButton"
aria-label="Search or jump to…"
aria-haspopup="dialog"
placeholder="Search or jump to..."
data-hotkey=s,/
autocapitalize="off"
data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;searchbar&quot;,&quot;context&quot;:&quot;global&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"
data-action="click:qbsearch-input#handleExpand"
>
<div class="mr-2 color-fg-muted">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search">
<path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path>
</svg>
</div>
<span class="flex-1" data-target="qbsearch-input.inputButtonText">Search or jump to...</span>
<div class="d-flex" data-target="qbsearch-input.hotkeyIndicator">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" aria-hidden="true" class="mr-1"><path fill="none" stroke="#979A9C" opacity=".4" d="M3.5.5h12c1.7 0 3 1.3 3 3v13c0 1.7-1.3 3-3 3h-12c-1.7 0-3-1.3-3-3v-13c0-1.7 1.3-3 3-3z"></path><path fill="#979A9C" d="M11.8 6L8 15.1h-.9L10.8 6h1z"></path></svg>
</div>
</button>
<input type="hidden" name="type" class="js-site-search-type-field">
<div class="Overlay--hidden " data-modal-dialog-overlay>
<modal-dialog data-action="close:qbsearch-input#handleClose cancel:qbsearch-input#handleClose" data-target="qbsearch-input.searchSuggestionsDialog" role="dialog" id="search-suggestions-dialog" aria-modal="true" aria-labelledby="search-suggestions-dialog-header" data-view-component="true" class="Overlay Overlay--width-large Overlay--height-auto">
<h1 id="search-suggestions-dialog-header" class="sr-only">Search code, repositories, users, issues, pull requests...</h1>
<div class="Overlay-body Overlay-body--paddingNone">
<div data-view-component="true"> <div class="search-suggestions position-fixed width-full color-shadow-large border color-fg-default color-bg-default overflow-hidden d-flex flex-column query-builder-container"
style="border-radius: 12px;"
data-target="qbsearch-input.queryBuilderContainer"
hidden
>
<!-- '"` --><!-- </textarea></xmp> --></option></form><form id="query-builder-test-form" action="" accept-charset="UTF-8" method="get">
<query-builder data-target="qbsearch-input.queryBuilder" id="query-builder-query-builder-test" data-filter-key=":" data-view-component="true" class="QueryBuilder search-query-builder">
<div class="FormControl FormControl--fullWidth">
<label id="query-builder-test-label" for="query-builder-test" class="FormControl-label sr-only">
Search
</label>
<div
class="QueryBuilder-StyledInput width-fit "
data-target="query-builder.styledInput"
>
<span id="query-builder-test-leadingvisual-wrap" class="FormControl-input-leadingVisualWrap QueryBuilder-leadingVisualWrap">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search FormControl-input-leadingVisual">
<path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path>
</svg>
</span>
<div data-target="query-builder.styledInputContainer" class="QueryBuilder-StyledInputContainer">
<div
aria-hidden="true"
class="QueryBuilder-StyledInputContent"
data-target="query-builder.styledInputContent"
></div>
<div class="QueryBuilder-InputWrapper">
<div aria-hidden="true" class="QueryBuilder-Sizer" data-target="query-builder.sizer"></div>
<input id="query-builder-test" name="query-builder-test" value="" autocomplete="off" type="text" role="combobox" spellcheck="false" aria-expanded="false" aria-describedby="validation-e15798ff-9072-41bb-a735-cfd6f72e4b30" data-target="query-builder.input" data-action="
input:query-builder#inputChange
blur:query-builder#inputBlur
keydown:query-builder#inputKeydown
focus:query-builder#inputFocus
" data-view-component="true" class="FormControl-input QueryBuilder-Input FormControl-medium" />
</div>
</div>
<span data-target="query-builder.clearButton" hidden>
<span class="sr-only" id="query-builder-test-clear">Clear</span>
<button role="button" id="query-builder-test-clear-button" aria-labelledby="query-builder-test-clear query-builder-test-label" data-action="
click:query-builder#clear
focus:query-builder#clearButtonFocus
blur:query-builder#clearButtonBlur
" variant="small" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium mr-1 tmp-mr-1 px-2 tmp-px-2 py-0 tmp-py-0 d-flex flex-items-center rounded-1 color-fg-muted"> <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x-circle-fill Button-visual">
<path d="M2.343 13.657A8 8 0 1 1 13.658 2.343 8 8 0 0 1 2.343 13.657ZM6.03 4.97a.751.751 0 0 0-1.042.018.751.751 0 0 0-.018 1.042L6.94 8 4.97 9.97a.749.749 0 0 0 .326 1.275.749.749 0 0 0 .734-.215L8 9.06l1.97 1.97a.749.749 0 0 0 1.275-.326.749.749 0 0 0-.215-.734L9.06 8l1.97-1.97a.749.749 0 0 0-.326-1.275.749.749 0 0 0-.734.215L8 6.94Z"></path>
</svg>
</button>
</span>
</div>
<template id="search-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search">
<path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path>
</svg>
</template>
<template id="code-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code">
<path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</template>
<template id="file-code-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-file-code">
<path d="M4 1.75C4 .784 4.784 0 5.75 0h5.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v8.586A1.75 1.75 0 0 1 14.25 15h-9a.75.75 0 0 1 0-1.5h9a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 10 4.25V1.5H5.75a.25.25 0 0 0-.25.25v2.5a.75.75 0 0 1-1.5 0Zm1.72 4.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l1.47-1.47-1.47-1.47a.75.75 0 0 1 0-1.06ZM3.28 7.78 1.81 9.25l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Zm8.22-6.218V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path>
</svg>
</template>
<template id="history-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-history">
<path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path>
</svg>
</template>
<template id="repo-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo">
<path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path>
</svg>
</template>
<template id="bookmark-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bookmark">
<path d="M3 2.75C3 1.784 3.784 1 4.75 1h6.5c.966 0 1.75.784 1.75 1.75v11.5a.75.75 0 0 1-1.227.579L8 11.722l-3.773 3.107A.751.751 0 0 1 3 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.91l3.023-2.489a.75.75 0 0 1 .954 0l3.023 2.49V2.75a.25.25 0 0 0-.25-.25Z"></path>
</svg>
</template>
<template id="plus-circle-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-plus-circle">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm7.25-3.25v2.5h2.5a.75.75 0 0 1 0 1.5h-2.5v2.5a.75.75 0 0 1-1.5 0v-2.5h-2.5a.75.75 0 0 1 0-1.5h2.5v-2.5a.75.75 0 0 1 1.5 0Z"></path>
</svg>
</template>
<template id="circle-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-dot-fill">
<path d="M8 4a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z"></path>
</svg>
</template>
<template id="trash-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-trash">
<path d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"></path>
</svg>
</template>
<template id="team-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-people">
<path d="M2 5.5a3.5 3.5 0 1 1 5.898 2.549 5.508 5.508 0 0 1 3.034 4.084.75.75 0 1 1-1.482.235 4 4 0 0 0-7.9 0 .75.75 0 0 1-1.482-.236A5.507 5.507 0 0 1 3.102 8.05 3.493 3.493 0 0 1 2 5.5ZM11 4a3.001 3.001 0 0 1 2.22 5.018 5.01 5.01 0 0 1 2.56 3.012.749.749 0 0 1-.885.954.752.752 0 0 1-.549-.514 3.507 3.507 0 0 0-2.522-2.372.75.75 0 0 1-.574-.73v-.352a.75.75 0 0 1 .416-.672A1.5 1.5 0 0 0 11 5.5.75.75 0 0 1 11 4Zm-5.5-.5a2 2 0 1 0-.001 3.999A2 2 0 0 0 5.5 3.5Z"></path>
</svg>
</template>
<template id="project-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project">
<path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25ZM11.75 3a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-1.5 0v-7.5a.75.75 0 0 1 .75-.75Zm-8.25.75a.75.75 0 0 1 1.5 0v5.5a.75.75 0 0 1-1.5 0ZM8 3a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 3Z"></path>
</svg>
</template>
<template id="pencil-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-pencil">
<path d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z"></path>
</svg>
</template>
<template id="copilot-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot">
<path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path>
</svg>
</template>
<template id="copilot-error-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot-error">
<path d="M16 11.24c0 .112-.072.274-.21.467L13 9.688V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-.198 0-.388-.009-.571-.029L6.833 5.226a4.01 4.01 0 0 0 .17-.782c.117-.935-.037-1.395-.241-1.614-.193-.206-.637-.413-1.682-.297-.683.076-1.115.231-1.395.415l-1.257-.91c.579-.564 1.413-.877 2.485-.996 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095Zm-5.083-8.707c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Zm2.511 11.074c-1.393.776-3.272 1.428-5.43 1.428-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.18-.455-.241-.963-.252-1.475L.31 4.107A.747.747 0 0 1 0 3.509V3.49a.748.748 0 0 1 .625-.73c.156-.026.306.047.435.139l14.667 10.578a.592.592 0 0 1 .227.264.752.752 0 0 1 .046.249v.022a.75.75 0 0 1-1.19.596Zm-1.367-.991L5.635 7.964a5.128 5.128 0 0 1-.889.073c-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433 1.539 0 3.089-.505 4.063-.934Z"></path>
</svg>
</template>
<template id="workflow-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-workflow">
<path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
</template>
<template id="book-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book">
<path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"></path>
</svg>
</template>
<template id="code-review-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-review">
<path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 13H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25v-8.5C0 1.784.784 1 1.75 1ZM1.5 2.75v8.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm5.28 1.72a.75.75 0 0 1 0 1.06L5.31 7l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.75.75 0 0 1 1.06 0Zm2.44 0a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L10.69 7 9.22 5.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</template>
<template id="codespaces-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-codespaces">
<path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path>
</svg>
</template>
<template id="comment-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment">
<path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
</template>
<template id="comment-discussion-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment-discussion">
<path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path>
</svg>
</template>
<template id="organization-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-organization">
<path d="M1.75 16A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 0 0 .25-.25V8.285a.25.25 0 0 0-.111-.208l-1.055-.703a.749.749 0 1 1 .832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0 1 14.25 16h-3.5a.766.766 0 0 1-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 0 1-.75-.75V14h-1v1.25a.75.75 0 0 1-.75.75Zm-.25-1.75c0 .138.112.25.25.25H4v-1.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 .75.75v1.25h2.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM3.75 6h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 3.75A.75.75 0 0 1 3.75 3h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 3.75Zm4 3A.75.75 0 0 1 7.75 6h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 7 6.75ZM7.75 3h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 9.75A.75.75 0 0 1 3.75 9h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 9.75ZM7.75 9h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path>
</svg>
</template>
<template id="rocket-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-rocket">
<path d="M14.064 0h.186C15.216 0 16 .784 16 1.75v.186a8.752 8.752 0 0 1-2.564 6.186l-.458.459c-.314.314-.641.616-.979.904v3.207c0 .608-.315 1.172-.833 1.49l-2.774 1.707a.749.749 0 0 1-1.11-.418l-.954-3.102a1.214 1.214 0 0 1-.145-.125L3.754 9.816a1.218 1.218 0 0 1-.124-.145L.528 8.717a.749.749 0 0 1-.418-1.11l1.71-2.774A1.748 1.748 0 0 1 3.31 4h3.204c.288-.338.59-.665.904-.979l.459-.458A8.749 8.749 0 0 1 14.064 0ZM8.938 3.623h-.002l-.458.458c-.76.76-1.437 1.598-2.02 2.5l-1.5 2.317 2.143 2.143 2.317-1.5c.902-.583 1.74-1.26 2.499-2.02l.459-.458a7.25 7.25 0 0 0 2.123-5.127V1.75a.25.25 0 0 0-.25-.25h-.186a7.249 7.249 0 0 0-5.125 2.123ZM3.56 14.56c-.732.732-2.334 1.045-3.005 1.148a.234.234 0 0 1-.201-.064.234.234 0 0 1-.064-.201c.103-.671.416-2.273 1.15-3.003a1.502 1.502 0 1 1 2.12 2.12Zm6.94-3.935c-.088.06-.177.118-.266.175l-2.35 1.521.548 1.783 1.949-1.2a.25.25 0 0 0 .119-.213ZM3.678 8.116 5.2 5.766c.058-.09.117-.178.176-.266H3.309a.25.25 0 0 0-.213.119l-1.2 1.95ZM12 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</template>
<template id="shield-check-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield-check">
<path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
</template>
<template id="heart-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-heart">
<path d="m8 14.25.345.666a.75.75 0 0 1-.69 0l-.008-.004-.018-.01a7.152 7.152 0 0 1-.31-.17 22.055 22.055 0 0 1-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.066 22.066 0 0 1-3.744 2.584l-.018.01-.006.003h-.002ZM4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.58 20.58 0 0 0 8 13.393a20.58 20.58 0 0 0 3.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.749.749 0 0 1-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5Z"></path>
</svg>
</template>
<template id="server-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-server">
<path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v4c0 .372-.116.717-.314 1 .198.283.314.628.314 1v4a1.75 1.75 0 0 1-1.75 1.75H1.75A1.75 1.75 0 0 1 0 12.75v-4c0-.358.109-.707.314-1a1.739 1.739 0 0 1-.314-1v-4C0 1.784.784 1 1.75 1ZM1.5 2.75v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm.25 5.75a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25ZM7 4.75A.75.75 0 0 1 7.75 4h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 7 4.75ZM7.75 10h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM3 4.75A.75.75 0 0 1 3.75 4h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 4.75ZM3.75 10h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path>
</svg>
</template>
<template id="globe-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-globe">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM5.78 8.75a9.64 9.64 0 0 0 1.363 4.177c.255.426.542.832.857 1.215.245-.296.551-.705.857-1.215A9.64 9.64 0 0 0 10.22 8.75Zm4.44-1.5a9.64 9.64 0 0 0-1.363-4.177c-.307-.51-.612-.919-.857-1.215a9.927 9.927 0 0 0-.857 1.215A9.64 9.64 0 0 0 5.78 7.25Zm-5.944 1.5H1.543a6.507 6.507 0 0 0 4.666 5.5c-.123-.181-.24-.365-.352-.552-.715-1.192-1.437-2.874-1.581-4.948Zm-2.733-1.5h2.733c.144-2.074.866-3.756 1.58-4.948.12-.197.237-.381.353-.552a6.507 6.507 0 0 0-4.666 5.5Zm10.181 1.5c-.144 2.074-.866 3.756-1.58 4.948-.12.197-.237.381-.353.552a6.507 6.507 0 0 0 4.666-5.5Zm2.733-1.5a6.507 6.507 0 0 0-4.666-5.5c.123.181.24.365.353.552.714 1.192 1.436 2.874 1.58 4.948Z"></path>
</svg>
</template>
<template id="issue-opened-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened">
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
</svg>
</template>
<template id="device-mobile-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-mobile">
<path d="M3.75 0h8.5C13.216 0 14 .784 14 1.75v12.5A1.75 1.75 0 0 1 12.25 16h-8.5A1.75 1.75 0 0 1 2 14.25V1.75C2 .784 2.784 0 3.75 0ZM3.5 1.75v12.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM8 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path>
</svg>
</template>
<template id="package-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-package">
<path d="m8.878.392 5.25 3.045c.54.314.872.89.872 1.514v6.098a1.75 1.75 0 0 1-.872 1.514l-5.25 3.045a1.75 1.75 0 0 1-1.756 0l-5.25-3.045A1.75 1.75 0 0 1 1 11.049V4.951c0-.624.332-1.201.872-1.514L7.122.392a1.75 1.75 0 0 1 1.756 0ZM7.875 1.69l-4.63 2.685L8 7.133l4.755-2.758-4.63-2.685a.248.248 0 0 0-.25 0ZM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432Zm6.25 8.271 4.625-2.683a.25.25 0 0 0 .125-.216V5.677L8.75 8.432Z"></path>
</svg>
</template>
<template id="credit-card-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-credit-card">
<path d="M10.75 9a.75.75 0 0 0 0 1.5h1.5a.75.75 0 0 0 0-1.5h-1.5Z"></path><path d="M0 3.75C0 2.784.784 2 1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25ZM14.5 6.5h-13v5.75c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25Zm0-2.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25V5h13Z"></path>
</svg>
</template>
<template id="play-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>
</svg>
</template>
<template id="gift-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-gift">
<path d="M2 2.75A2.75 2.75 0 0 1 4.75 0c.983 0 1.873.42 2.57 1.232.268.318.497.668.68 1.042.183-.375.411-.725.68-1.044C9.376.42 10.266 0 11.25 0a2.75 2.75 0 0 1 2.45 4h.55c.966 0 1.75.784 1.75 1.75v2c0 .698-.409 1.301-1 1.582v4.918A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25V9.332C.409 9.05 0 8.448 0 7.75v-2C0 4.784.784 4 1.75 4h.55c-.192-.375-.3-.8-.3-1.25ZM7.25 9.5H2.5v4.75c0 .138.112.25.25.25h4.5Zm1.5 0v5h4.5a.25.25 0 0 0 .25-.25V9.5Zm0-4V8h5.5a.25.25 0 0 0 .25-.25v-2a.25.25 0 0 0-.25-.25Zm-7 0a.25.25 0 0 0-.25.25v2c0 .138.112.25.25.25h5.5V5.5h-5.5Zm3-4a1.25 1.25 0 0 0 0 2.5h2.309c-.233-.818-.542-1.401-.878-1.793-.43-.502-.915-.707-1.431-.707ZM8.941 4h2.309a1.25 1.25 0 0 0 0-2.5c-.516 0-1 .205-1.43.707-.337.392-.646.975-.879 1.793Z"></path>
</svg>
</template>
<template id="code-square-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-square">
<path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
</template>
<template id="device-desktop-icon">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-desktop">
<path d="M14.25 1c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 14.25 12h-3.727c.099 1.041.52 1.872 1.292 2.757A.752.752 0 0 1 11.25 16h-6.5a.75.75 0 0 1-.565-1.243c.772-.885 1.192-1.716 1.292-2.757H1.75A1.75 1.75 0 0 1 0 10.25v-7.5C0 1.784.784 1 1.75 1ZM1.75 2.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25ZM9.018 12H6.982a5.72 5.72 0 0 1-.765 2.5h3.566a5.72 5.72 0 0 1-.765-2.5Z"></path>
</svg>
</template>
<div class="position-relative">
<ul
role="listbox"
class="ActionListWrap QueryBuilder-ListWrap"
aria-label="Suggestions"
data-action="
combobox-commit:query-builder#comboboxCommit
mousedown:query-builder#resultsMousedown
"
data-target="query-builder.resultsList"
data-persist-list=false
id="query-builder-test-results"
tabindex="-1"
></ul>
</div>
<div class="FormControl-inlineValidation" id="validation-e15798ff-9072-41bb-a735-cfd6f72e4b30" hidden="hidden">
<span class="FormControl-inlineValidation--visual">
<svg aria-hidden="true" data-component="Octicon" height="12" viewBox="0 0 12 12" version="1.1" width="12" data-view-component="true" class="octicon octicon-alert-fill">
<path d="M4.855.708c.5-.896 1.79-.896 2.29 0l4.675 8.351a1.312 1.312 0 0 1-1.146 1.954H1.33A1.313 1.313 0 0 1 .183 9.058ZM7 7V3H5v4Zm-1 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"></path>
</svg>
</span>
<span></span>
</div> </div>
<div data-target="query-builder.screenReaderFeedback" aria-live="polite" aria-atomic="true" class="sr-only"></div>
</query-builder></form>
<div class="d-flex flex-row color-fg-muted tmp-px-3 text-small color-bg-default search-feedback-prompt">
<a target="_blank" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax" data-view-component="true" class="Link color-fg-accent text-normal ml-2 tmp-ml-2">Search syntax tips</a> <div class="d-flex flex-1"></div>
</div>
</div>
</div>
</div>
</modal-dialog></div>
</div>
<div data-action="click:qbsearch-input#retract" class="dark-backdrop position-fixed" hidden data-target="qbsearch-input.darkBackdrop"></div>
<div class="color-fg-default">
<dialog-helper>
<dialog data-target="qbsearch-input.feedbackDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="feedback-dialog" aria-modal="true" aria-labelledby="feedback-dialog-title" aria-describedby="feedback-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll">
<div data-view-component="true" class="Overlay-header">
<div class="Overlay-headerContentWrap">
<div class="Overlay-titleWrap">
<h1 class="Overlay-title " id="feedback-dialog-title">
Provide feedback
</h1>
</div>
<div class="Overlay-actionWrap">
<button data-close-dialog-id="feedback-dialog" aria-label="Close" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg></button>
</div>
</div>
</div>
<scrollable-region data-labelled-by="feedback-dialog-title">
<div data-view-component="true" class="Overlay-body"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="code-search-feedback-form" data-turbo="false" action="/search/feedback" accept-charset="UTF-8" method="post"><input type="hidden" data-csrf="true" name="authenticity_token" value="8JTh52gVPgewdFuOrJHn3yXM+TFqwgXI0lIDtroOL3YldYOkTE8AKF8W3rflCAzfAtSm/u34pAhv70TQVsIIuQ==" />
<p>We read every piece of feedback, and take your input very seriously.</p>
<textarea name="feedback" class="form-control width-full mb-2" style="height: 120px" id="feedback"></textarea>
<input name="include_email" id="include_email" aria-label="Include my email address so I can be contacted" class="form-control mr-2" type="checkbox">
<label for="include_email" style="font-weight: normal">Include my email address so I can be contacted</label>
</form></div>
</scrollable-region>
<div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd"> <button data-close-dialog-id="feedback-dialog" type="button" data-view-component="true" class="btn"> Cancel
</button>
<button form="code-search-feedback-form" data-action="click:qbsearch-input#submitFeedback" type="submit" data-view-component="true" class="btn-primary btn"> Submit feedback
</button>
</div>
</dialog></dialog-helper>
<custom-scopes data-target="qbsearch-input.customScopesManager">
<dialog-helper>
<dialog data-target="custom-scopes.customScopesModalDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="custom-scopes-dialog" aria-modal="true" aria-labelledby="custom-scopes-dialog-title" aria-describedby="custom-scopes-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll">
<div data-view-component="true" class="Overlay-header Overlay-header--divided">
<div class="Overlay-headerContentWrap">
<div class="Overlay-titleWrap">
<h1 class="Overlay-title " id="custom-scopes-dialog-title">
Saved searches
</h1>
<h2 id="custom-scopes-dialog-description" class="Overlay-description">Use saved searches to filter your results more quickly</h2>
</div>
<div class="Overlay-actionWrap">
<button data-close-dialog-id="custom-scopes-dialog" aria-label="Close" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg></button>
</div>
</div>
</div>
<scrollable-region data-labelled-by="custom-scopes-dialog-title">
<div data-view-component="true" class="Overlay-body"> <div data-target="custom-scopes.customScopesModalDialogFlash"></div>
<div hidden class="create-custom-scope-form" data-target="custom-scopes.createCustomScopeForm">
<!-- '"` --><!-- </textarea></xmp> --></option></form><form id="custom-scopes-dialog-form" data-turbo="false" action="/search/custom_scopes" accept-charset="UTF-8" method="post"><input type="hidden" data-csrf="true" name="authenticity_token" value="JpOYFPyXW62GiNNKjQv9KwQqZn7DolHPmIP/x3sNvHf8dRkOltsKcpqAaEJ+MskzWmsXwNWIOwPt/W3TEeOobw==" />
<div data-target="custom-scopes.customScopesModalDialogFlash"></div>
<input type="hidden" id="custom_scope_id" name="custom_scope_id" data-target="custom-scopes.customScopesIdField">
<div class="form-group">
<label for="custom_scope_name">Name</label>
<auto-check src="/search/custom_scopes/check_name" required>
<input
type="text"
name="custom_scope_name"
id="custom_scope_name"
data-target="custom-scopes.customScopesNameField"
class="form-control"
autocomplete="off"
placeholder="github-ruby"
required
maxlength="50">
<input type="hidden" data-csrf="true" value="OU6S9Xr40UWZiTFDu2clUBHmEEzcPkiO3WFCaUZEOuj+LNFM6aM0IqxuB22UBVEhyOaTPeDP1yi8y+LzyhnDJg==" />
</auto-check>
</div>
<div class="form-group">
<label for="custom_scope_query">Query</label>
<input
type="text"
name="custom_scope_query"
id="custom_scope_query"
data-target="custom-scopes.customScopesQueryField"
class="form-control"
autocomplete="off"
placeholder="(repo:mona/a OR repo:mona/b) AND lang:python"
required
maxlength="500">
</div>
<p class="text-small color-fg-muted">
To see all available qualifiers, see our <a class="Link--inTextBlock" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax">documentation</a>.
</p>
</form> </div>
<div data-target="custom-scopes.manageCustomScopesForm">
<div data-target="custom-scopes.list"></div>
</div>
</div>
</scrollable-region>
<div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd Overlay-footer--divided"> <button data-action="click:custom-scopes#customScopesCancel" type="button" data-view-component="true" class="btn"> Cancel
</button>
<button form="custom-scopes-dialog-form" data-action="click:custom-scopes#customScopesSubmit" data-target="custom-scopes.customScopesSubmitButton" type="submit" data-view-component="true" class="btn-primary btn"> Create saved search
</button>
</div>
</dialog></dialog-helper>
</custom-scopes>
</div>
</qbsearch-input>
<div class="position-relative HeaderMenu-link-wrap d-lg-inline-block">
<a
href="/login?return_to=https%3A%2F%2Fgithub.com%2Fswicg%2Factivitypub-e2ee%2Fissues%2F56"
class="HeaderMenu-link HeaderMenu-link--sign-in HeaderMenu-button flex-shrink-0 no-underline d-none d-lg-inline-flex border border-lg-0 rounded px-2 py-1"
style="margin-left: 12px;"
data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/swicg/activitypub-e2ee/issues/56&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="9a5bd50f43bb22dd8261e33fac3f8c78f18622cfbdf5d1f589b851fe9a460f98"
data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to go to homepage&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Sign in;ref_loc:Header&quot;}"
>
Sign in
</a>
</div>
<a href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&amp;source=header-repo&amp;source_repo=swicg%2Factivitypub-e2ee"
class="HeaderMenu-link HeaderMenu-link--sign-up HeaderMenu-button flex-shrink-0 d-flex d-lg-inline-flex no-underline border color-border-default rounded px-2 py-1"
data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/swicg/activitypub-e2ee/issues/56&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="9a5bd50f43bb22dd8261e33fac3f8c78f18622cfbdf5d1f589b851fe9a460f98"
data-analytics-event="{&quot;category&quot;:&quot;Sign up&quot;,&quot;action&quot;:&quot;click to sign up for account&quot;,&quot;label&quot;:&quot;ref_page:/&lt;user-name&gt;/&lt;repo-name&gt;/voltron/issues_fragments/issue_layout;ref_cta:Sign up;ref_loc:header logged out&quot;}"
>
Sign up
</a>
<div class="AppHeader-appearanceSettings">
<react-partial-anchor>
<button data-target="react-partial-anchor.anchor" id="icon-button-3213738b-f96f-40ff-9562-0bd9f19f1ce3" aria-labelledby="tooltip-257d5653-5a2c-4bd2-bfe0-deb0b610f608" type="button" disabled="disabled" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium AppHeader-button HeaderMenu-link border cursor-wait"> <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-sliders Button-visual">
<path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path>
</svg>
</button><tool-tip id="tooltip-257d5653-5a2c-4bd2-bfe0-deb0b610f608" for="icon-button-3213738b-f96f-40ff-9562-0bd9f19f1ce3" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Appearance settings</tool-tip>
<template data-target="react-partial-anchor.template">
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/appearance-settings.3690bbff0a0fd071.module.css" />
<react-partial
partial-name="appearance-settings"
data-ssr="false"
data-attempted-ssr="false"
data-react-profiling="false"
>
<script type="application/json" data-target="react-partial.embeddedData">{"props":{}}</script>
<div data-target="react-partial.reactRoot"></div>
</react-partial>
</template>
</react-partial-anchor>
</div>
<button type="button" class="sr-only js-header-menu-focus-trap d-block d-lg-none">Resetting focus</button>
</div>
</div>
</div>
</div>
</header>
<div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
<path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
<span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
<span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
<span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
<button id="icon-button-66ef404a-283d-458f-a266-3c507d722e84" aria-labelledby="tooltip-1fd0977f-a750-4e1a-b53c-2c2867e57ffa" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close"> <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual">
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button><tool-tip id="tooltip-1fd0977f-a750-4e1a-b53c-2c2867e57ffa" for="icon-button-66ef404a-283d-458f-a266-3c507d722e84" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip>
</div>
</div>
<div id="start-of-content" class="show-on-focus"></div>
<div id="js-flash-container" class="flash-container" data-turbo-replace>
<template class="js-flash-template">
<div class="flash flash-full {{ className }}">
<div >
<button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button>
<div aria-atomic="true" role="alert" class="js-flash-alert">
<div>{{ message }}</div>
</div>
</div>
</div>
</template>
</div>
<div
class="application-main "
data-commit-hovercards-enabled
data-discussion-hovercards-enabled
data-issue-and-pr-hovercards-enabled
data-project-hovercards-enabled
>
<div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
<main id="js-repo-pjax-container" >
<div id="repository-container-header" class="tmp-pt-3 hide-full-screen" style="background-color: var(--page-header-bgColor, var(--color-page-header-bg));" data-turbo-replace>
<div class="d-flex flex-nowrap flex-justify-end tmp-mb-3 tmp-px-3 tmp-px-lg-5" style="gap: 1rem;">
<div class="flex-auto min-width-0 width-fit">
<div class=" d-flex flex-wrap flex-items-center wb-break-word f3 text-normal">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo color-fg-muted mr-2 tmp-mr-2">
<path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path>
</svg>
<span class="author flex-self-stretch" itemprop="author">
<a class="url fn" rel="author" data-hovercard-type="organization" data-hovercard-url="/orgs/swicg/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/swicg">
swicg
</a> </span>
<span class="mx-1 flex-self-stretch color-fg-muted">/</span>
<strong itemprop="name" class="mr-2 flex-self-stretch">
<a data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" href="/swicg/activitypub-e2ee">activitypub-e2ee</a>
</strong>
<span></span><span class="Label Label--secondary v-align-middle mr-1">Public</span>
</div>
</div>
<div id="repository-details-container" class="flex-shrink-0" data-turbo-replace style="max-width: 70%;">
<ul class="pagehead-actions flex-shrink-0 d-none d-md-inline" style="padding: 2px 0;">
<li>
<a href="/login?return_to=%2Fswicg%2Factivitypub-e2ee" rel="nofollow" id="repository-details-watch-button" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/swicg/activitypub-e2ee/issues/56&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="e24f496c5ac090c22b6ff475accfa52a8533574953653e773cdc0d201da6b9b4" aria-label="You must be signed in to change notification settings" data-view-component="true" class="btn-sm btn"> <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell mr-2 tmp-mr-2">
<path d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z"></path>
</svg>Notifications
</a> <tool-tip id="tooltip-09ac38b5-c810-419f-8788-c381f837286a" for="repository-details-watch-button" popover="manual" data-direction="s" data-type="description" data-view-component="true" class="sr-only position-absolute">You must be signed in to change notification settings</tool-tip>
</li>
<li>
<a icon="repo-forked" id="fork-button" href="/login?return_to=%2Fswicg%2Factivitypub-e2ee" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:804531295,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/swicg/activitypub-e2ee/issues/56&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="7a59f75df51bbc77389dd62e901519e44f8c8a1cda3e5040b3c7f912ac2406cc" data-view-component="true" class="btn-sm btn"> <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-2 tmp-mr-2">
<path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path>
</svg>Fork
<span id="repo-network-counter" data-pjax-replace="true" data-turbo-replace="true" title="2" data-view-component="true" class="Counter">2</span>
</a>
</li>
<li>
<div data-view-component="true" class="BtnGroup d-flex">
<a href="/login?return_to=%2Fswicg%2Factivitypub-e2ee" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:804531295,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/swicg/activitypub-e2ee/issues/56&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="6540259920597ae5738aa00ee004a8828679efcc52aa9ca5b35e72112f70e9ed" aria-label="You must be signed in to star a repository" data-view-component="true" class="tooltipped tooltipped-sw btn-sm btn"> <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star v-align-text-bottom d-inline-block mr-2 tmp-mr-2">
<path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
</svg><span data-view-component="true" class="d-inline">
Star
</span> <span id="repo-stars-counter-star" aria-label="68 users starred this repository" data-singular-suffix="user starred this repository" data-plural-suffix="users starred this repository" data-turbo-replace="true" title="68" data-view-component="true" class="Counter js-social-count">68</span>
</a></div>
</li>
</ul>
</div>
</div>
<div id="responsive-meta-container" data-turbo-replace>
</div>
<nav data-pjax="#js-repo-pjax-container" aria-label="Repository" data-view-component="true" class="js-repo-nav js-sidenav-container-pjax js-responsive-underlinenav overflow-hidden UnderlineNav px-3 tmp-px-3 px-md-4 tmp-px-md-4 px-lg-5 tmp-px-lg-5">
<ul data-view-component="true" class="UnderlineNav-body list-style-none">
<li data-view-component="true" class="d-inline-flex">
<a id="code-tab" href="/swicg/activitypub-e2ee" data-tab-item="i0code-tab" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments repo_attestations /swicg/activitypub-e2ee" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g c" data-command-id="repositories:go-to-code" data-react-nav="code-view" data-react-nav-anchor="code-view-repo-link" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Code&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code UnderlineNav-octicon d-none d-sm-inline">
<path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
<span data-content="Code">Code</span>
<span id="code-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>
</a></li>
<li data-view-component="true" class="d-inline-flex">
<a id="issues-tab" href="/swicg/activitypub-e2ee/issues" data-tab-item="i1issues-tab" data-selected-links="repo_issues repo_labels repo_milestones /swicg/activitypub-e2ee/issues" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g i" data-command-id="repositories:go-to-issues" data-react-nav="issues-react" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Issues&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" aria-current="page" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item selected">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline">
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
</svg>
<span data-content="Issues">Issues</span>
<span id="issues-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="75" data-view-component="true" class="Counter">75</span>
</a></li>
<li data-view-component="true" class="d-inline-flex">
<a id="pull-requests-tab" href="/swicg/activitypub-e2ee/pulls" data-tab-item="i2pull-requests-tab" data-selected-links="repo_pulls checks /swicg/activitypub-e2ee/pulls" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g p" data-command-id="repositories:go-to-pull-requests" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Pull requests&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request UnderlineNav-octicon d-none d-sm-inline">
<path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path>
</svg>
<span data-content="Pull requests">Pull requests</span>
<span id="pull-requests-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span>
</a></li>
<li data-view-component="true" class="d-inline-flex">
<a id="actions-tab" href="/swicg/activitypub-e2ee/actions" data-tab-item="i3actions-tab" data-selected-links="repo_actions /swicg/activitypub-e2ee/actions" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g a" data-command-id="repositories:go-to-actions" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Actions&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play UnderlineNav-octicon d-none d-sm-inline">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>
</svg>
<span data-content="Actions">Actions</span>
<span id="actions-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>
</a></li>
<li data-view-component="true" class="d-inline-flex">
<a id="projects-tab" href="/swicg/activitypub-e2ee/projects" data-tab-item="i4projects-tab" data-selected-links="repo_projects new_repo_project repo_project /swicg/activitypub-e2ee/projects" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g b" data-command-id="repositories:go-to-projects" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Projects&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon d-none d-sm-inline">
<path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path>
</svg>
<span data-content="Projects">Projects</span>
<span id="projects-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>
</a></li>
<li data-view-component="true" class="d-inline-flex">
<a id="security-and-quality-tab" href="/swicg/activitypub-e2ee/security" data-tab-item="i5security-and-quality-tab" data-selected-links="security overview alerts policy token_scanning code_scanning /swicg/activitypub-e2ee/security" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g s" data-command-id="repositories:go-to-security" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Security and quality&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield UnderlineNav-octicon d-none d-sm-inline">
<path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
<span data-content="Security and quality">Security and quality</span>
<span id="security-and-quality-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span>
</a></li>
<li data-view-component="true" class="d-inline-flex">
<a id="insights-tab" href="/swicg/activitypub-e2ee/pulse" data-tab-item="i6insights-tab" data-selected-links="repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /swicg/activitypub-e2ee/pulse" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-command-id="repositories:go-to-insights" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Insights&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph UnderlineNav-octicon d-none d-sm-inline">
<path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
<span data-content="Insights">Insights</span>
<span id="insights-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>
</a></li>
</ul>
<div style="visibility:hidden;" data-view-component="true" class="UnderlineNav-actions js-responsive-underlinenav-overflow position-absolute pr-3 tmp-pr-3 pr-md-4 tmp-pr-md-4 pr-lg-5 tmp-pr-lg-5 right-0"> <action-menu data-select-variant="none" data-view-component="true">
<focus-group direction="vertical" mnemonics retain>
<button id="action-menu-9a6e0cb1-88c4-43f6-9730-a6ac5f53edb9-button" popovertarget="action-menu-9a6e0cb1-88c4-43f6-9730-a6ac5f53edb9-overlay" aria-controls="action-menu-9a6e0cb1-88c4-43f6-9730-a6ac5f53edb9-list" aria-haspopup="true" aria-labelledby="tooltip-0ff206cc-210f-44fb-9c9b-d23ac159e182" type="button" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--medium UnderlineNav-item"> <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal Button-visual">
<path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path>
</svg>
</button><tool-tip id="tooltip-0ff206cc-210f-44fb-9c9b-d23ac159e182" for="action-menu-9a6e0cb1-88c4-43f6-9730-a6ac5f53edb9-button" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Additional navigation options</tool-tip>
<anchored-position data-target="action-menu.overlay" id="action-menu-9a6e0cb1-88c4-43f6-9730-a6ac5f53edb9-overlay" anchor="action-menu-9a6e0cb1-88c4-43f6-9730-a6ac5f53edb9-button" align="start" side="outside-bottom" anchor-offset="normal" popover="auto" data-view-component="true">
<div data-view-component="true" class="Overlay Overlay--size-auto">
<div data-view-component="true" class="Overlay-body Overlay-body--paddingNone"> <action-list>
<div data-view-component="true">
<ul aria-labelledby="action-menu-9a6e0cb1-88c4-43f6-9730-a6ac5f53edb9-button" id="action-menu-9a6e0cb1-88c4-43f6-9730-a6ac5f53edb9-list" role="menu" data-view-component="true" class="ActionListWrap--inset ActionListWrap">
<li hidden="hidden" data-menu-item="i0code-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
<a tabindex="-1" id="item-3b342456-9fd3-438c-bade-3254cd849a8d" href="/swicg/activitypub-e2ee" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
<span class="ActionListItem-visual ActionListItem-visual--leading">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code">
<path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</span>
<span data-view-component="true" class="ActionListItem-label">
Code
</span>
</a>
</li>
<li hidden="hidden" data-menu-item="i1issues-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
<a tabindex="-1" id="item-a5234dcd-17b8-412b-bad4-bc12aea4fb1d" href="/swicg/activitypub-e2ee/issues" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
<span class="ActionListItem-visual ActionListItem-visual--leading">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened">
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
</svg>
</span>
<span data-view-component="true" class="ActionListItem-label">
Issues
</span>
</a>
</li>
<li hidden="hidden" data-menu-item="i2pull-requests-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
<a tabindex="-1" id="item-1f63c5c4-2f02-405f-8701-14cd7b7b50df" href="/swicg/activitypub-e2ee/pulls" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
<span class="ActionListItem-visual ActionListItem-visual--leading">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request">
<path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path>
</svg>
</span>
<span data-view-component="true" class="ActionListItem-label">
Pull requests
</span>
</a>
</li>
<li hidden="hidden" data-menu-item="i3actions-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
<a tabindex="-1" id="item-54a58f65-40fd-407c-81f9-fbfc89b5dfdd" href="/swicg/activitypub-e2ee/actions" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
<span class="ActionListItem-visual ActionListItem-visual--leading">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play">
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>
</svg>
</span>
<span data-view-component="true" class="ActionListItem-label">
Actions
</span>
</a>
</li>
<li hidden="hidden" data-menu-item="i4projects-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
<a tabindex="-1" id="item-93f6e36f-6c39-45bf-9b74-9b50e08a3ca6" href="/swicg/activitypub-e2ee/projects" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
<span class="ActionListItem-visual ActionListItem-visual--leading">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table">
<path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path>
</svg>
</span>
<span data-view-component="true" class="ActionListItem-label">
Projects
</span>
</a>
</li>
<li hidden="hidden" data-menu-item="i5security-and-quality-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
<a tabindex="-1" id="item-ad3e6d20-c574-416e-b5c3-28d149a36d8f" href="/swicg/activitypub-e2ee/security" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
<span class="ActionListItem-visual ActionListItem-visual--leading">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield">
<path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span>
<span data-view-component="true" class="ActionListItem-label">
Security and quality
</span>
</a>
</li>
<li hidden="hidden" data-menu-item="i6insights-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
<a tabindex="-1" id="item-d786982c-60f6-4568-9357-26416808aaf7" href="/swicg/activitypub-e2ee/pulse" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
<span class="ActionListItem-visual ActionListItem-visual--leading">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph">
<path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
</span>
<span data-view-component="true" class="ActionListItem-label">
Insights
</span>
</a>
</li>
</ul>
</div></action-list>
</div>
</div></anchored-position> </focus-group>
</action-menu></div>
</nav>
</div>
<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class="">
<div id="repo-content-pjax-container" class="repository-content " >
<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class=""><react-app
app-name="issues-react"
initial-path="/swicg/activitypub-e2ee/issues/56"
style="display: block; min-height: calc(100vh - 64px);"
data-attempted-ssr="true"
data-ssr="true"
data-lazy="false"
data-alternate="false"
data-data-router-enabled="false"
data-react-profiling="false"
>
<script type="application/json" data-target="react-app.embeddedData">{"payload":{"preloaded_records":{},"structured_data":{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Maintaining ordering in the group conversation","articleBody":"Ordering is very important in MLS. We need to have a way to have an official ordering.","author":{"url":"https://github.com/evanp","@type":"Person","name":"evanp"},"datePublished":"2026-01-08T15:26:08.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":7},"url":"https://github.com/56/activitypub-e2ee/issues/56"},"best_match_sort_enabled":false,"tabbed_timeline":false,"preloadedQueries":[{"queryId":"930f2e0464d1b74cdd206ed7f12d0b19","queryName":"IssueViewerViewQuery","variables":{"count":15,"number":56,"owner":"swicg","repo":"activitypub-e2ee"},"result":{"data":{"repository":{"id":"R_kgDOL_QsXw","isOwnerEnterpriseManaged":false,"owner":{"__typename":"Organization","userNameDisplayConfiguration":"HANDLE","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx"},"issue":{"id":"I_kwDOL_QsX87iGb3t","number":56,"repository":{"name":"activitypub-e2ee","owner":{"__typename":"Organization","login":"swicg","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx","url":"https://github.com/swicg","databaseId":23560971,"issueFieldsEnabled":false,"pinnedIssueFields":{"nodes":[]}},"id":"R_kgDOL_QsXw","nameWithOwner":"swicg/activitypub-e2ee","isArchived":false,"isWritable":true,"isPrivate":false,"databaseId":804531295,"slashCommandsEnabled":false,"visibility":"PUBLIC","viewerCanPush":false,"viewerCanInteract":false,"viewerInteractionLimitReasonHTML":"","isCopilotAgentEnabled":null,"pinnedIssues":{"totalCount":0},"viewerCanPinIssues":false,"viewerIssueCreationPermissions":{"triageable":false},"issueTypes":{"edges":[{"node":{"id":"IT_kwDOAWeDC84ASngz"}},{"node":{"id":"IT_kwDOAWeDC84ASng2"}},{"node":{"id":"IT_kwDOAWeDC84ASng3"}}]}},"updatedAt":"2026-05-07T14:39:36Z","title":"Maintaining ordering in the group conversation","titleHTML":"Maintaining ordering in the group conversation","url":"https://github.com/swicg/activitypub-e2ee/issues/56","viewerCanUpdateNext":false,"issueType":null,"state":"OPEN","stateReason":null,"duplicateOf":null,"linkedPullRequests":{"nodes":[]},"agentAssignments":[],"linkedPullRequestsIncludingClosed":{"nodes":[]},"subIssuesSummary":{"total":0,"completed":0},"__isLabelable":"Issue","labels":{"edges":[],"pageInfo":{"endCursor":null,"hasNextPage":false}},"__isNode":"Issue","assignedActors":{"nodes":[{"__typename":"User","__isActor":"User","id":"MDQ6VXNlcjY3NzA=","login":"evanp","name":"Evan Prodromou","profileResourcePath":"/evanp","avatarUrl":"https://avatars.githubusercontent.com/u/6770?s=64\u0026u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","__isNode":"User"}]},"milestone":null,"databaseId":3793337837,"viewerDidAuthor":false,"locked":false,"author":{"__isActor":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA=","profileUrl":"https://github.com/evanp","name":"Evan Prodromou","avatarUrl":"https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","__typename":"User"},"__isComment":"Issue","body":"Ordering is very important in MLS. We need to have a way to have an official ordering.","bodyHTML":"\u003cp dir=\"auto\"\u003eOrdering is very important in MLS. We need to have a way to have an official ordering.\u003c/p\u003e","bodyVersion":"5b5939a49a8a842a03a2dca42d308a767486118b464e56089b7ceee7398d28fe","createdAt":"2026-01-08T15:26:08Z","__isReactable":"Issue","reactionGroups":[{"content":"THUMBS_UP","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"THUMBS_DOWN","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"LAUGH","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HOORAY","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"CONFUSED","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HEART","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"ROCKET","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"EYES","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}}],"viewerCanUpdateMetadata":false,"pinnedIssueComment":null,"viewerCanComment":false,"viewerCanAssign":false,"viewerCanLabel":false,"__isIssueOrPullRequest":"Issue","projectItems":{"edges":[],"pageInfo":{"endCursor":null,"hasNextPage":false}},"viewerCanSetMilestone":false,"isPinned":false,"viewerCanDelete":false,"viewerCanTransfer":false,"viewerCanConvertToDiscussion":false,"viewerCanLock":false,"viewerCanType":false,"viewerCanSetFields":false,"issueFieldValues":{"nodes":[]},"frontTimelineItems":{"pageInfo":{"hasNextPage":false,"endCursor":"Y3Vyc29yOnYyOpPPAAABngLhPEAAqjQzOTgwOTExNzQ="},"totalCount":13,"edges":[{"node":{"__typename":"IssueComment","__isIssueTimelineItems":"IssueComment","databaseId":3724407041,"viewerDidAuthor":false,"issue":{"author":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA="},"id":"I_kwDOL_QsX87iGb3t","number":56,"locked":false,"databaseId":3793337837},"author":{"__typename":"User","login":"evanp","avatarUrl":"https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","profileUrl":"https://github.com/evanp","id":"MDQ6VXNlcjY3NzA=","name":"Evan Prodromou"},"id":"IC_kwDOL_QsX87d_fEB","body":"One way to do this is with a collection that's maintained on the group initiator's server. Similar to the `thread` collection:\n\nhttps://codeberg.org/fediverse/fep/src/branch/main/fep/76ea/fep-76ea.md\n\n...however, the messages in the conversation aren't related with an `inReplyTo` property in MLS in ActivityPub.","bodyHTML":"\u003cp dir=\"auto\"\u003eOne way to do this is with a collection that's maintained on the group initiator's server. Similar to the \u003ccode class=\"notranslate\"\u003ethread\u003c/code\u003e collection:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"https://codeberg.org/fediverse/fep/src/branch/main/fep/76ea/fep-76ea.md\" rel=\"nofollow\"\u003ehttps://codeberg.org/fediverse/fep/src/branch/main/fep/76ea/fep-76ea.md\u003c/a\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e...however, the messages in the conversation aren't related with an \u003ccode class=\"notranslate\"\u003einReplyTo\u003c/code\u003e property in MLS in ActivityPub.\u003c/p\u003e","bodyVersion":"9d995413ec701c5791289109cd8b22fcae452080fef1ed3bcd78f688e96eb670","viewerCanUpdate":false,"url":"https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3724407041","createdAt":"2026-01-08T15:32:24Z","authorAssociation":"COLLABORATOR","viewerCanDelete":false,"viewerCanMinimize":false,"viewerCanUnminimize":false,"viewerCanReport":false,"viewerCanReportToMaintainer":false,"viewerCanBlockFromOrg":false,"viewerCanUnblockFromOrg":false,"viewerCanPin":false,"viewerCanUnpin":false,"viaApp":null,"isHidden":false,"minimizedReason":null,"showSpammyBadge":false,"createdViaEmail":false,"authorToRepoOwnerSponsorship":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","owner":{"__typename":"Organization","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx","login":"swicg","url":"https://github.com/swicg"},"isPrivate":false,"slashCommandsEnabled":false,"nameWithOwner":"swicg/activitypub-e2ee","databaseId":804531295},"__isComment":"IssueComment","viewerCanReadUserContentEdits":true,"lastEditedAt":"2026-01-08T15:39:35Z","lastUserContentEdit":{"editor":{"__typename":"User","url":"https://github.com/evanp","login":"evanp","id":"MDQ6VXNlcjY3NzA="},"id":"UCE_lALOL_QsX87d_fEBzo9UzI4"},"pinnedBy":null,"__isReactable":"IssueComment","reactionGroups":[{"content":"THUMBS_UP","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"THUMBS_DOWN","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"LAUGH","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HOORAY","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"CONFUSED","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HEART","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"ROCKET","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"EYES","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}}],"__isNode":"IssueComment"},"cursor":"Y3Vyc29yOnYyOpPPAAABm548z0AAqjM3MjQ0MDcwNDE="},{"node":{"__typename":"CrossReferencedEvent","__isIssueTimelineItems":"CrossReferencedEvent","__isTimelineEvent":"CrossReferencedEvent","databaseId":4321069764,"createdAt":"2026-01-08T15:37:10Z","actor":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA=","__isActor":"User","avatarUrl":"https://avatars.githubusercontent.com/u/6770?s=64\u0026u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","profileResourcePath":"/evanp","name":"Evan Prodromou"},"source":{"__typename":"Issue","__isNode":"Issue","id":"I_kwDOL_QsX87iGi98"},"willCloseTarget":false,"referencedAt":"2026-01-08T15:37:09Z","innerSource":{"__typename":"Issue","__isReferencedSubject":"Issue","id":"I_kwDOL_QsX87iGi98","issueTitleHTML":"Ordering of Commit Messages","url":"https://github.com/swicg/activitypub-e2ee/issues/57","number":57,"stateReason":"COMPLETED","repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","isPrivate":false,"owner":{"__typename":"Organization","login":"swicg","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx"}},"__isNode":"Issue"},"__isNode":"CrossReferencedEvent","id":"CRE_kwDOL_QsX88AAAABAY5KxA"},"cursor":"Y3Vyc29yOnYyOpPPAAABm55BLHACqjQzMjEwNjk3NjQ="},{"node":{"__typename":"IssueComment","__isIssueTimelineItems":"IssueComment","databaseId":3724435190,"viewerDidAuthor":false,"issue":{"author":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA="},"id":"I_kwDOL_QsX87iGb3t","number":56,"locked":false,"databaseId":3793337837},"author":{"__typename":"User","login":"evanp","avatarUrl":"https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","profileUrl":"https://github.com/evanp","id":"MDQ6VXNlcjY3NzA=","name":"Evan Prodromou"},"id":"IC_kwDOL_QsX87d_l72","body":"@keks had a good description of the problem in #57 .\n\n\u003e Hi all! After talking to @mayel today, I skimmed the spec and I think I couldn't find any discussion of a challenge that many who want to use MLS in decentralized/distributed/federated settings face: the ordering of commits. The architecture document, though a bit high-level, has a [section][mlsarch-delivery] on it.\n\n\u003e The core issue is that when you merge a commit, you should more or less immediately throw away the key material of the old epoch. The spec allows a little bit of leeway, but at the end of the day this is a problem for forward secrecy: leaving the old keys around means that when the device is compromised, messages from previous epochs can be decrypted.\n\n\u003e Over in Matrix they had tried building \"[DMLS]\", which roughly does eventual consistency for MLS. Work on that angle seems to have stopped (imho that's good because \"i am going to delete the old encryption keys eventually\" is not a strong security statement). [Another proposal][MSC4256] suggests using the home server (similar to instance) of the group creator as an arbiter for the ordering of commits. \n\n\u003e I just wanted to raise this issue because it's tricky to weigh the trade-offs and it would be a shame if it had to be addressed too late in the process.\n\n[DMLS]: https://gitlab.matrix.org/uhoreg/matrix-dmls\n[MSC4256]: https://github.com/matrix-org/matrix-spec-proposals/pull/4256\n[mlsarch-delivery]: https://www.rfc-editor.org/rfc/rfc9750.html#name-delivery-of-messages\n","bodyHTML":"\u003cp dir=\"auto\"\u003e\u003ca class=\"user-mention notranslate\" data-hovercard-type=\"user\" data-hovercard-url=\"/users/keks/hovercard\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"https://github.com/keks\"\u003e@keks\u003c/a\u003e had a good description of the problem in \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"3793366908\" data-permission-text=\"Title is private\" data-url=\"https://github.com/swicg/activitypub-e2ee/issues/57\" data-hovercard-type=\"issue\" data-hovercard-url=\"/swicg/activitypub-e2ee/issues/57/hovercard\" href=\"https://github.com/swicg/activitypub-e2ee/issues/57\"\u003e#57\u003c/a\u003e .\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eHi all! After talking to \u003ca class=\"user-mention notranslate\" data-hovercard-type=\"user\" data-hovercard-url=\"/users/mayel/hovercard\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"https://github.com/mayel\"\u003e@mayel\u003c/a\u003e today, I skimmed the spec and I think I couldn't find any discussion of a challenge that many who want to use MLS in decentralized/distributed/federated settings face: the ordering of commits. The architecture document, though a bit high-level, has a \u003ca href=\"https://www.rfc-editor.org/rfc/rfc9750.html#name-delivery-of-messages\" rel=\"nofollow\"\u003esection\u003c/a\u003e on it.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eThe core issue is that when you merge a commit, you should more or less immediately throw away the key material of the old epoch. The spec allows a little bit of leeway, but at the end of the day this is a problem for forward secrecy: leaving the old keys around means that when the device is compromised, messages from previous epochs can be decrypted.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eOver in Matrix they had tried building \"\u003ca href=\"https://gitlab.matrix.org/uhoreg/matrix-dmls\" rel=\"nofollow\"\u003eDMLS\u003c/a\u003e\", which roughly does eventual consistency for MLS. Work on that angle seems to have stopped (imho that's good because \"i am going to delete the old encryption keys eventually\" is not a strong security statement). \u003ca href=\"https://github.com/matrix-org/matrix-spec-proposals/pull/4256\" data-hovercard-type=\"pull_request\" data-hovercard-url=\"/matrix-org/matrix-spec-proposals/pull/4256/hovercard\"\u003eAnother proposal\u003c/a\u003e suggests using the home server (similar to instance) of the group creator as an arbiter for the ordering of commits.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eI just wanted to raise this issue because it's tricky to weigh the trade-offs and it would be a shame if it had to be addressed too late in the process.\u003c/p\u003e\n\u003c/blockquote\u003e","bodyVersion":"104cfd97c71d0854ea404c025ad28b56fc016853af70ab405a0f762ac68d7596","viewerCanUpdate":false,"url":"https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3724435190","createdAt":"2026-01-08T15:38:12Z","authorAssociation":"COLLABORATOR","viewerCanDelete":false,"viewerCanMinimize":false,"viewerCanUnminimize":false,"viewerCanReport":false,"viewerCanReportToMaintainer":false,"viewerCanBlockFromOrg":false,"viewerCanUnblockFromOrg":false,"viewerCanPin":false,"viewerCanUnpin":false,"viaApp":null,"isHidden":false,"minimizedReason":null,"showSpammyBadge":false,"createdViaEmail":false,"authorToRepoOwnerSponsorship":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","owner":{"__typename":"Organization","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx","login":"swicg","url":"https://github.com/swicg"},"isPrivate":false,"slashCommandsEnabled":false,"nameWithOwner":"swicg/activitypub-e2ee","databaseId":804531295},"__isComment":"IssueComment","viewerCanReadUserContentEdits":true,"lastEditedAt":null,"lastUserContentEdit":null,"pinnedBy":null,"__isReactable":"IssueComment","reactionGroups":[{"content":"THUMBS_UP","viewerHasReacted":false,"reactors":{"totalCount":1,"nodes":[{"__typename":"User","login":"mayel","__isNode":"User","id":"MDQ6VXNlcjExNTMxOA=="}]}},{"content":"THUMBS_DOWN","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"LAUGH","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HOORAY","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"CONFUSED","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HEART","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"ROCKET","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"EYES","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}}],"__isNode":"IssueComment"},"cursor":"Y3Vyc29yOnYyOpPPAAABm55CHqAAqjM3MjQ0MzUxOTA="},{"node":{"__typename":"CrossReferencedEvent","__isIssueTimelineItems":"CrossReferencedEvent","__isTimelineEvent":"CrossReferencedEvent","databaseId":4321188544,"createdAt":"2026-01-08T15:58:39Z","actor":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA=","__isActor":"User","avatarUrl":"https://avatars.githubusercontent.com/u/6770?s=64\u0026u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","profileResourcePath":"/evanp","name":"Evan Prodromou"},"source":{"__typename":"Issue","__isNode":"Issue","id":"I_kwDOL_QsX87f-Y-1"},"willCloseTarget":false,"referencedAt":"2026-01-08T15:58:38Z","innerSource":{"__typename":"Issue","__isReferencedSubject":"Issue","id":"I_kwDOL_QsX87f-Y-1","issueTitleHTML":"Messages by group","url":"https://github.com/swicg/activitypub-e2ee/issues/50","number":50,"stateReason":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","isPrivate":false,"owner":{"__typename":"Organization","login":"swicg","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx"}},"__isNode":"Issue"},"__isNode":"CrossReferencedEvent","id":"CRE_kwDOL_QsX88AAAABAZAawA"},"cursor":"Y3Vyc29yOnYyOpPPAAABm55U15gCqjQzMjExODg1NDQ="},{"node":{"__typename":"AssignedEvent","__isIssueTimelineItems":"AssignedEvent","__isTimelineEvent":"AssignedEvent","databaseId":22322335001,"createdAt":"2026-01-27T16:10:41Z","actor":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA=","__isActor":"User","avatarUrl":"https://avatars.githubusercontent.com/u/6770?s=64\u0026u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","profileResourcePath":"/evanp","name":"Evan Prodromou"},"assignee":{"__typename":"User","id":"MDQ6VXNlcjY3NzA=","__isNode":"User","__isActor":"User","login":"evanp","resourcePath":"/evanp","name":"Evan Prodromou"},"__isNode":"AssignedEvent","id":"AE_lADOL_QsX87iGb3tzwAAAAUyg80Z"},"cursor":"Y3Vyc29yOnYyOpPPAAABnAA4r-gBqzIyMzIyMzM1MDAx"},{"node":{"__typename":"IssueComment","__isIssueTimelineItems":"IssueComment","databaseId":3847943860,"viewerDidAuthor":false,"issue":{"author":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA="},"id":"I_kwDOL_QsX87iGb3t","number":56,"locked":false,"databaseId":3793337837},"author":{"__typename":"User","login":"uhoreg","avatarUrl":"https://avatars.githubusercontent.com/u/1012976?v=4","profileUrl":"https://github.com/uhoreg","id":"MDQ6VXNlcjEwMTI5NzY=","name":"Hubert Chathi"},"id":"IC_kwDOL_QsX87lWva0","body":"FWIW, I just gave a talk at FOSDEM that explored some different attempts at using MLS in a decentralized/distributed environment: https://fosdem.org/2026/schedule/event/STAXFT-dmls_vs_dmls_decentralizingdistributing_messaging_layer_security/","bodyHTML":"\u003cp dir=\"auto\"\u003eFWIW, I just gave a talk at FOSDEM that explored some different attempts at using MLS in a decentralized/distributed environment: \u003ca href=\"https://fosdem.org/2026/schedule/event/STAXFT-dmls_vs_dmls_decentralizingdistributing_messaging_layer_security/\" rel=\"nofollow\"\u003ehttps://fosdem.org/2026/schedule/event/STAXFT-dmls_vs_dmls_decentralizingdistributing_messaging_layer_security/\u003c/a\u003e\u003c/p\u003e","bodyVersion":"e146314e6f487cab8114a7cfb4edb967b535032ac9f253dd6e241e2cefdde4b8","viewerCanUpdate":false,"url":"https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3847943860","createdAt":"2026-02-04T14:56:16Z","authorAssociation":"NONE","viewerCanDelete":false,"viewerCanMinimize":false,"viewerCanUnminimize":false,"viewerCanReport":false,"viewerCanReportToMaintainer":false,"viewerCanBlockFromOrg":false,"viewerCanUnblockFromOrg":false,"viewerCanPin":false,"viewerCanUnpin":false,"viaApp":null,"isHidden":false,"minimizedReason":null,"showSpammyBadge":false,"createdViaEmail":false,"authorToRepoOwnerSponsorship":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","owner":{"__typename":"Organization","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx","login":"swicg","url":"https://github.com/swicg"},"isPrivate":false,"slashCommandsEnabled":false,"nameWithOwner":"swicg/activitypub-e2ee","databaseId":804531295},"__isComment":"IssueComment","viewerCanReadUserContentEdits":true,"lastEditedAt":null,"lastUserContentEdit":null,"pinnedBy":null,"__isReactable":"IssueComment","reactionGroups":[{"content":"THUMBS_UP","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"THUMBS_DOWN","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"LAUGH","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HOORAY","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"CONFUSED","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HEART","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"ROCKET","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"EYES","viewerHasReacted":false,"reactors":{"totalCount":1,"nodes":[{"__typename":"User","login":"mayel","__isNode":"User","id":"MDQ6VXNlcjExNTMxOA=="}]}}],"__isNode":"IssueComment"},"cursor":"Y3Vyc29yOnYyOpPPAAABnCknboAAqjM4NDc5NDM4NjA="},{"node":{"__typename":"CrossReferencedEvent","__isIssueTimelineItems":"CrossReferencedEvent","__isTimelineEvent":"CrossReferencedEvent","databaseId":4797959995,"createdAt":"2026-02-19T19:50:22Z","actor":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA=","__isActor":"User","avatarUrl":"https://avatars.githubusercontent.com/u/6770?s=64\u0026u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","profileResourcePath":"/evanp","name":"Evan Prodromou"},"source":{"__typename":"Issue","__isNode":"Issue","id":"I_kwDOL_QsX87sUaXe"},"willCloseTarget":false,"referencedAt":"2026-02-19T19:50:21Z","innerSource":{"__typename":"Issue","__isReferencedSubject":"Issue","id":"I_kwDOL_QsX87sUaXe","issueTitleHTML":"Agenda - 25 Feb 2026","url":"https://github.com/swicg/activitypub-e2ee/issues/61","number":61,"stateReason":"COMPLETED","repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","isPrivate":false,"owner":{"__typename":"Organization","login":"swicg","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx"}},"__isNode":"Issue"},"__isNode":"CrossReferencedEvent","id":"CRE_kwDOL_QsX88AAAABHfsPOw"},"cursor":"Y3Vyc29yOnYyOpPPAAABnHd0FDACqjQ3OTc5NTk5OTU="},{"node":{"__typename":"IssueComment","__isIssueTimelineItems":"IssueComment","databaseId":3960528442,"viewerDidAuthor":false,"issue":{"author":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA="},"id":"I_kwDOL_QsX87iGb3t","number":56,"locked":false,"databaseId":3793337837},"author":{"__typename":"User","login":"evanp","avatarUrl":"https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","profileUrl":"https://github.com/evanp","id":"MDQ6VXNlcjY3NzA=","name":"Evan Prodromou"},"id":"IC_kwDOL_QsX87sEN46","body":"Using a defined `context` with an `OrderedCollection` would help with this.\n\nChecking `published` order rather than received order is also good. I can check what the granularity on `published` is.\n\nKey renewal is up to the clients. Should happen when add/remove a client. Otherwise, we should check on the recommended time for this.","bodyHTML":"\u003cp dir=\"auto\"\u003eUsing a defined \u003ccode class=\"notranslate\"\u003econtext\u003c/code\u003e with an \u003ccode class=\"notranslate\"\u003eOrderedCollection\u003c/code\u003e would help with this.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eChecking \u003ccode class=\"notranslate\"\u003epublished\u003c/code\u003e order rather than received order is also good. I can check what the granularity on \u003ccode class=\"notranslate\"\u003epublished\u003c/code\u003e is.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eKey renewal is up to the clients. Should happen when add/remove a client. Otherwise, we should check on the recommended time for this.\u003c/p\u003e","bodyVersion":"b82030c6fc57af685062409a56051e1ae1d41336aa21ac6f23102065752a01ed","viewerCanUpdate":false,"url":"https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3960528442","createdAt":"2026-02-25T16:37:25Z","authorAssociation":"COLLABORATOR","viewerCanDelete":false,"viewerCanMinimize":false,"viewerCanUnminimize":false,"viewerCanReport":false,"viewerCanReportToMaintainer":false,"viewerCanBlockFromOrg":false,"viewerCanUnblockFromOrg":false,"viewerCanPin":false,"viewerCanUnpin":false,"viaApp":null,"isHidden":false,"minimizedReason":null,"showSpammyBadge":false,"createdViaEmail":false,"authorToRepoOwnerSponsorship":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","owner":{"__typename":"Organization","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx","login":"swicg","url":"https://github.com/swicg"},"isPrivate":false,"slashCommandsEnabled":false,"nameWithOwner":"swicg/activitypub-e2ee","databaseId":804531295},"__isComment":"IssueComment","viewerCanReadUserContentEdits":true,"lastEditedAt":null,"lastUserContentEdit":null,"pinnedBy":null,"__isReactable":"IssueComment","reactionGroups":[{"content":"THUMBS_UP","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"THUMBS_DOWN","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"LAUGH","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HOORAY","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"CONFUSED","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HEART","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"ROCKET","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"EYES","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}}],"__isNode":"IssueComment"},"cursor":"Y3Vyc29yOnYyOpPPAAABnJWplYgAqjM5NjA1Mjg0NDI="},{"node":{"__typename":"IssueComment","__isIssueTimelineItems":"IssueComment","databaseId":3962083019,"viewerDidAuthor":false,"issue":{"author":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA="},"id":"I_kwDOL_QsX87iGb3t","number":56,"locked":false,"databaseId":3793337837},"author":{"__typename":"User","login":"uhoreg","avatarUrl":"https://avatars.githubusercontent.com/u/1012976?v=4","profileUrl":"https://github.com/uhoreg","id":"MDQ6VXNlcjEwMTI5NzY=","name":"Hubert Chathi"},"id":"IC_kwDOL_QsX87sKJbL","body":"It's not just about needing an ordering to the messages, but you also need to ensure that everyone receives the messages in the same order. (This includes ensuring that senders know, at the time of sending, that their message comes after someone else's message.) Because the purpose of the ordering in MLS is that Commit messages that are sent \"too late\" are discarded. But if someone has already applied the Commit, before they find out that it should have been disregarded, they'll be unable to participate in the group any further.\n\nFor example, if Alice and Bob both try to send a commit message based on the same epoch (say, Epoch 1). Alice's message is ordered first, but Carol receives Bob's message first. When Carol receives Bob's message, she applies Bob's commit, giving her an Epoch 2. At this point, she throws out the Epoch 1 `epoch_secret`, because MLS requires this for forward secrecy. She then receives Alice's message, which she find out should have been applied instead of Bob's, but since she already threw out the Epoch 1 `epoch_secret`, she can't create Alice's Epoch 2.","bodyHTML":"\u003cp dir=\"auto\"\u003eIt's not just about needing an ordering to the messages, but you also need to ensure that everyone receives the messages in the same order. (This includes ensuring that senders know, at the time of sending, that their message comes after someone else's message.) Because the purpose of the ordering in MLS is that Commit messages that are sent \"too late\" are discarded. But if someone has already applied the Commit, before they find out that it should have been disregarded, they'll be unable to participate in the group any further.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor example, if Alice and Bob both try to send a commit message based on the same epoch (say, Epoch 1). Alice's message is ordered first, but Carol receives Bob's message first. When Carol receives Bob's message, she applies Bob's commit, giving her an Epoch 2. At this point, she throws out the Epoch 1 \u003ccode class=\"notranslate\"\u003eepoch_secret\u003c/code\u003e, because MLS requires this for forward secrecy. She then receives Alice's message, which she find out should have been applied instead of Bob's, but since she already threw out the Epoch 1 \u003ccode class=\"notranslate\"\u003eepoch_secret\u003c/code\u003e, she can't create Alice's Epoch 2.\u003c/p\u003e","bodyVersion":"6212dfd3dabde2ca4d94c23d411209d15e8eede7963499a0f0a64ea6aca720bc","viewerCanUpdate":false,"url":"https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3962083019","createdAt":"2026-02-25T21:07:23Z","authorAssociation":"NONE","viewerCanDelete":false,"viewerCanMinimize":false,"viewerCanUnminimize":false,"viewerCanReport":false,"viewerCanReportToMaintainer":false,"viewerCanBlockFromOrg":false,"viewerCanUnblockFromOrg":false,"viewerCanPin":false,"viewerCanUnpin":false,"viaApp":null,"isHidden":false,"minimizedReason":null,"showSpammyBadge":false,"createdViaEmail":false,"authorToRepoOwnerSponsorship":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","owner":{"__typename":"Organization","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx","login":"swicg","url":"https://github.com/swicg"},"isPrivate":false,"slashCommandsEnabled":false,"nameWithOwner":"swicg/activitypub-e2ee","databaseId":804531295},"__isComment":"IssueComment","viewerCanReadUserContentEdits":true,"lastEditedAt":null,"lastUserContentEdit":null,"pinnedBy":null,"__isReactable":"IssueComment","reactionGroups":[{"content":"THUMBS_UP","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"THUMBS_DOWN","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"LAUGH","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HOORAY","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"CONFUSED","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HEART","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"ROCKET","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"EYES","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}}],"__isNode":"IssueComment"},"cursor":"Y3Vyc29yOnYyOpPPAAABnJagvvgAqjM5NjIwODMwMTk="},{"node":{"__typename":"IssueComment","__isIssueTimelineItems":"IssueComment","databaseId":4396216497,"viewerDidAuthor":false,"issue":{"author":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA="},"id":"I_kwDOL_QsX87iGb3t","number":56,"locked":false,"databaseId":3793337837},"author":{"__typename":"User","login":"mayel","avatarUrl":"https://avatars.githubusercontent.com/u/115318?u=4f2952ec42029ef082f2df76560bfc0b7e1e5ab4\u0026v=4","profileUrl":"https://github.com/mayel","id":"MDQ6VXNlcjExNTMxOA==","name":"Mayel de Borniol"},"id":"IC_kwDOL_QsX88AAAABBgjwsQ","body":"So after learning more about MLS, doing an initial implementation, and encountering some challenges with self-removals (see #80), here's an attempt at a proposal for a group actor approach which can serve as coordination hub for self-removal, decommission, and commit ordering.\n\n## Problem\n\nMLS requires that epoch secrets be discarded immediately after a Commit is applied. This means ordering errors are irrecoverable, as @uhoreg described above. This rules out eventual-consistency approaches. Every member must receive Commits in the **same order**, not just *an* order.\n\nIn a more P2P federated model, each member has an independent inbox with independent delivery latency, there is no shared total order. Timer-based staggering (as in our current implementation for self-removal from a group) reduces the collision probability but does not eliminate it, and adds latency proportional to group size.\n\n### Self-removal and decommission\n\nMLS imposes a further constraint: **a device cannot commit its own removal.** MLS's RFC 9420 only allows a member to issue a Remove *Proposal* for itself; another group member must produce and distribute the resulting Commit. In a federated group, coordinating which member commits, and ensuring all others receive that Commit in the correct order, is the same ordering problem, applied specifically to leave and decommission flows.\n\n## Prior discussions\n\nIn https://github.com/swicg/activitypub-e2ee/issues/80 @benpate frames the solution space as three approaches:\n\n1. **Designated committer**: only one device may commit epoch-incrementing proposals. Simple but impractical for real groups (e.g. that commiter client may be offline for a while).\n2. **Server-side epoch locking via a group relay actor**: a single actor orders and rejects duplicate-epoch Commits. Solves ordering and also fixes membership metadata leakage. Requires group-relay infrastructure. Also suggested in https://github.com/swicg/activitypub-e2ee/issues/78#issuecomment-4372911159\n3. **First-commit-wins + conflict detection**: timer/jitter-based staggering. No extra infrastructure, but fragile and adds latency proportional to group size.\n\n@evanp similarly suggested an `OrderedCollection` on the group initiator's server, and Matrix's MSC4256 proposes the group creator's server as ordering arbiter.\n\n## Proposed approach: group actor as AP-level sequencer\n\nThe Group actor pattern (described in https://github.com/swicg/activitypub-e2ee/issues/83, Options C and D1) is a realisation of the group relay idea using existing ActivityPub primitives ([FEP-1b12](https://codeberg.org/fediverse/fep/src/branch/main/fep/1b12/fep-1b12.md)).\n\nA Group actor on the origin server (i.e. the group creator's server) can act as a single inbox for all group MLS traffic. Because all members POST to the same inbox, the group actor's `Announce` stream provides a **total order** over all proposals and commits that every member observes identically, eliminating races without timers. `published` timestamps on activities provide a secondary ordering signal, but inbox-arrival order at a single actor is the authoritative sequence.\n\n### Self-removal and decommission\n\nThe leaving device sends its MLS Remove Proposal (as a `PrivateMessage`) to the group actor:\n\n```json\n{\n \"type\": \"Create\",\n \"actor\": \"https://server-b/users/bob\",\n \"to\": [\"https://server-a/group\"],\n \"object\": {\n \"type\": \"PrivateMessage\",\n \"mediaType\": \"message/mls\",\n \"encoding\": \"base64\",\n \"content\": \"\u003cbase64-encoded MLS Remove Proposal\u003e\"\n }\n}\n```\n\nThe group actor Announces this to all members. Any coordination strategy can then be used to decide who commits (e.g. a co-device of the leaving member if one exists, a designated member by leaf index, or a timer-based fallback) but all of these are now **safe**: the group actor requires no MLS knowledge, it simply forwards all activities in inbox-arrival order. Clients apply the first valid Commit for their current epoch from the Announce stream and discard any subsequent one as `WrongEpoch`. All members observe the same ordered stream and land on the same winner.\n\nA decommissioning device similarly sends Remove Proposals to each group actor it belongs to. \n\n### Commit ordering \n\nThe race condition is not specific to removal — it applies to any operation where multiple members could produce a valid Commit for the same epoch simultaneously: adding a new member, key rotation (UpdatePath), or any batch of pending proposals. In a pure P2P model, resolving these races requires timer-based staggering for every Commit-producing operation.\n\nRouting all MLS group operations (Proposals, Commits, Welcomes) through the group actor solves this generally. Members send to the group actor via C2S; the group actor Announces to all followers in inbox-arrival order. All members see the same ordered stream of group state changes.\n\nRFC 9420 §3.2 allows a committer to apply their Commit immediately only if they have assurance it will be the next one applied by the group. Receiving it back via the group actor's Announce stream is that assurance, it confirms the Commit is in the group actor's outbox and was the first to arrive for this epoch. Until that echo-back arrives, the client has no such assurance and must not apply.\n\nThe client workflow:\n1. Generate Commit, send to group actor, do **not** apply locally yet\n2. Watch the Announce stream:\n - Own Commit arrives first → confirmed winner, apply it, advance epoch\n - A competing Commit arrives first → discard pending Commit, apply the received one, re-propose if needed\n\nThe group actor forwards everything blindly in arrival order; clients use the ordered Announce stream to determine the winner. Together they eliminate the irrecoverable race without the group actor needing any MLS knowledge.\n\n\n## Two proposed changes\n\nThis proposal bundles two distinct changes:\n\n**1. Infrastructure: group actor as AP-level sequencer**\nA Group actor on the origin server provides a single inbox for all group MLS traffic and distributes an ordered Announce stream to all members. This is the delivery ordering mechanism, also described in https://github.com/swicg/activitypub-e2ee/issues/83 (options C and D1).\n\n**2. Client protocol change: apply Commits on receive, not on generation**\nCurrently, MLS-over-AP clients (including our implementation) apply a Commit immediately upon generating it. This proposal requires clients to instead hold the Commit in a pending state and apply it only when it arrives back via the authoritative channel (the group actor's Announce stream). This is the behavioral change that makes ordering guarantees meaningful, without it, the group actor's total order is irrelevant because clients have already diverged. \n\nIt also implies that potentially **any** ordered delivery channel (not only a group actor) could provide the same safety property, if clients adopt this behavior.\n\n## Tradeoffs\n\n| | Timer-based P2P (current) | Group actor hub |\n|---|---|---|\n| Commit ordering | Timer stagger, fragile | Total order via inbox |\n| Self-removal latency | `leafIndex × 2s` + co-device window | Near-instant (first committer wins deterministically) |\n| Single point of failure | None | Group actor's server |\n| Privacy | Each server sees full member list (can be mitigated by `bto`) | Hub sees server-level topology only (if using option D1) |\n| Infrastructure required | None | Group actor support (FEP-1b12) |\n\n## Relationship to #83\n\nThe same Group actor infrastructure that mitigates membership metadata exposure (Options C and D1 in #83) can also solve these MLS coordination problems. Implementing a group actor hub gives both privacy and ordering benefits with a single new infrastructure component.\n\n## Open questions\n\n- Is there interest in speccing the group actor as MLS coordination layer?\n- Should the group actor be a *required* component for federated MLS groups, or remain optional with P2P timer-based fallback?\n- Does the inbox-ordering guarantee hold across all AP server implementations, or do we need an explicit sequence number on activities?\n- If the group *creator* leaves the group, the sequencer itself can continue to function as long as the origin server accepts to keep the group running. \n- If the group actor's server goes offline, the group loses its sequencer entirely, and no new messages can be ordered or delivered. This is a critical reliability and sustainability concern. Supporting `Move` activity on groups can help, at least for planned server sun-setting.\n","bodyHTML":"\u003cp dir=\"auto\"\u003eSo after learning more about MLS, doing an initial implementation, and encountering some challenges with self-removals (see \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"4366700770\" data-permission-text=\"Title is private\" data-url=\"https://github.com/swicg/activitypub-e2ee/issues/80\" data-hovercard-type=\"issue\" data-hovercard-url=\"/swicg/activitypub-e2ee/issues/80/hovercard\" href=\"https://github.com/swicg/activitypub-e2ee/issues/80\"\u003e#80\u003c/a\u003e), here's an attempt at a proposal for a group actor approach which can serve as coordination hub for self-removal, decommission, and commit ordering.\u003c/p\u003e\n\u003ch2 dir=\"auto\"\u003eProblem\u003c/h2\u003e\n\u003cp dir=\"auto\"\u003eMLS requires that epoch secrets be discarded immediately after a Commit is applied. This means ordering errors are irrecoverable, as \u003ca class=\"user-mention notranslate\" data-hovercard-type=\"user\" data-hovercard-url=\"/users/uhoreg/hovercard\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"https://github.com/uhoreg\"\u003e@uhoreg\u003c/a\u003e described above. This rules out eventual-consistency approaches. Every member must receive Commits in the \u003cstrong\u003esame order\u003c/strong\u003e, not just \u003cem\u003ean\u003c/em\u003e order.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn a more P2P federated model, each member has an independent inbox with independent delivery latency, there is no shared total order. Timer-based staggering (as in our current implementation for self-removal from a group) reduces the collision probability but does not eliminate it, and adds latency proportional to group size.\u003c/p\u003e\n\u003ch3 dir=\"auto\"\u003eSelf-removal and decommission\u003c/h3\u003e\n\u003cp dir=\"auto\"\u003eMLS imposes a further constraint: \u003cstrong\u003ea device cannot commit its own removal.\u003c/strong\u003e MLS's RFC 9420 only allows a member to issue a Remove \u003cem\u003eProposal\u003c/em\u003e for itself; another group member must produce and distribute the resulting Commit. In a federated group, coordinating which member commits, and ensuring all others receive that Commit in the correct order, is the same ordering problem, applied specifically to leave and decommission flows.\u003c/p\u003e\n\u003ch2 dir=\"auto\"\u003ePrior discussions\u003c/h2\u003e\n\u003cp dir=\"auto\"\u003eIn \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"4366700770\" data-permission-text=\"Title is private\" data-url=\"https://github.com/swicg/activitypub-e2ee/issues/80\" data-hovercard-type=\"issue\" data-hovercard-url=\"/swicg/activitypub-e2ee/issues/80/hovercard\" href=\"https://github.com/swicg/activitypub-e2ee/issues/80\"\u003e#80\u003c/a\u003e \u003ca class=\"user-mention notranslate\" data-hovercard-type=\"user\" data-hovercard-url=\"/users/benpate/hovercard\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"https://github.com/benpate\"\u003e@benpate\u003c/a\u003e frames the solution space as three approaches:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eDesignated committer\u003c/strong\u003e: only one device may commit epoch-incrementing proposals. Simple but impractical for real groups (e.g. that commiter client may be offline for a while).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eServer-side epoch locking via a group relay actor\u003c/strong\u003e: a single actor orders and rejects duplicate-epoch Commits. Solves ordering and also fixes membership metadata leakage. Requires group-relay infrastructure. Also suggested in \u003cspan class=\"reference\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-issue-opened open mr-1\" title=\"Open\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"\u003e\u003c/path\u003e\u003cpath d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"4291886325\" data-permission-text=\"Title is private\" data-url=\"https://github.com/swicg/activitypub-e2ee/issues/78\" data-hovercard-type=\"issue\" data-hovercard-url=\"/swicg/activitypub-e2ee/issues/78/hovercard?comment_id=4372911159\u0026amp;comment_type=issue_comment\" href=\"https://github.com/swicg/activitypub-e2ee/issues/78#issuecomment-4372911159\"\u003eHandling messages from blocked users\u003cspan class=\"issue-shorthand\"\u003e #78 (comment)\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFirst-commit-wins + conflict detection\u003c/strong\u003e: timer/jitter-based staggering. No extra infrastructure, but fragile and adds latency proportional to group size.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003e\u003ca class=\"user-mention notranslate\" data-hovercard-type=\"user\" data-hovercard-url=\"/users/evanp/hovercard\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"https://github.com/evanp\"\u003e@evanp\u003c/a\u003e similarly suggested an \u003ccode class=\"notranslate\"\u003eOrderedCollection\u003c/code\u003e on the group initiator's server, and Matrix's MSC4256 proposes the group creator's server as ordering arbiter.\u003c/p\u003e\n\u003ch2 dir=\"auto\"\u003eProposed approach: group actor as AP-level sequencer\u003c/h2\u003e\n\u003cp dir=\"auto\"\u003eThe Group actor pattern (described in \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"4397863233\" data-permission-text=\"Title is private\" data-url=\"https://github.com/swicg/activitypub-e2ee/issues/83\" data-hovercard-type=\"issue\" data-hovercard-url=\"/swicg/activitypub-e2ee/issues/83/hovercard\" href=\"https://github.com/swicg/activitypub-e2ee/issues/83\"\u003e#83\u003c/a\u003e, Options C and D1) is a realisation of the group relay idea using existing ActivityPub primitives (\u003ca href=\"https://codeberg.org/fediverse/fep/src/branch/main/fep/1b12/fep-1b12.md\" rel=\"nofollow\"\u003eFEP-1b12\u003c/a\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eA Group actor on the origin server (i.e. the group creator's server) can act as a single inbox for all group MLS traffic. Because all members POST to the same inbox, the group actor's \u003ccode class=\"notranslate\"\u003eAnnounce\u003c/code\u003e stream provides a \u003cstrong\u003etotal order\u003c/strong\u003e over all proposals and commits that every member observes identically, eliminating races without timers. \u003ccode class=\"notranslate\"\u003epublished\u003c/code\u003e timestamps on activities provide a secondary ordering signal, but inbox-arrival order at a single actor is the authoritative sequence.\u003c/p\u003e\n\u003ch3 dir=\"auto\"\u003eSelf-removal and decommission\u003c/h3\u003e\n\u003cp dir=\"auto\"\u003eThe leaving device sends its MLS Remove Proposal (as a \u003ccode class=\"notranslate\"\u003ePrivateMessage\u003c/code\u003e) to the group actor:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n \u0026quot;type\u0026quot;: \u0026quot;Create\u0026quot;,\n \u0026quot;actor\u0026quot;: \u0026quot;https://server-b/users/bob\u0026quot;,\n \u0026quot;to\u0026quot;: [\u0026quot;https://server-a/group\u0026quot;],\n \u0026quot;object\u0026quot;: {\n \u0026quot;type\u0026quot;: \u0026quot;PrivateMessage\u0026quot;,\n \u0026quot;mediaType\u0026quot;: \u0026quot;message/mls\u0026quot;,\n \u0026quot;encoding\u0026quot;: \u0026quot;base64\u0026quot;,\n \u0026quot;content\u0026quot;: \u0026quot;\u0026lt;base64-encoded MLS Remove Proposal\u0026gt;\u0026quot;\n }\n}\"\u003e\u003cpre class=\"notranslate\"\u003e{\n \u003cspan class=\"pl-ent\"\u003e\"type\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eCreate\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"actor\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://server-b/users/bob\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"to\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://server-a/group\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n \u003cspan class=\"pl-ent\"\u003e\"object\"\u003c/span\u003e: {\n \u003cspan class=\"pl-ent\"\u003e\"type\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ePrivateMessage\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"mediaType\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003emessage/mls\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"encoding\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ebase64\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"content\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u0026lt;base64-encoded MLS Remove Proposal\u0026gt;\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe group actor Announces this to all members. Any coordination strategy can then be used to decide who commits (e.g. a co-device of the leaving member if one exists, a designated member by leaf index, or a timer-based fallback) but all of these are now \u003cstrong\u003esafe\u003c/strong\u003e: the group actor requires no MLS knowledge, it simply forwards all activities in inbox-arrival order. Clients apply the first valid Commit for their current epoch from the Announce stream and discard any subsequent one as \u003ccode class=\"notranslate\"\u003eWrongEpoch\u003c/code\u003e. All members observe the same ordered stream and land on the same winner.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eA decommissioning device similarly sends Remove Proposals to each group actor it belongs to.\u003c/p\u003e\n\u003ch3 dir=\"auto\"\u003eCommit ordering\u003c/h3\u003e\n\u003cp dir=\"auto\"\u003eThe race condition is not specific to removal — it applies to any operation where multiple members could produce a valid Commit for the same epoch simultaneously: adding a new member, key rotation (UpdatePath), or any batch of pending proposals. In a pure P2P model, resolving these races requires timer-based staggering for every Commit-producing operation.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRouting all MLS group operations (Proposals, Commits, Welcomes) through the group actor solves this generally. Members send to the group actor via C2S; the group actor Announces to all followers in inbox-arrival order. All members see the same ordered stream of group state changes.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRFC 9420 §3.2 allows a committer to apply their Commit immediately only if they have assurance it will be the next one applied by the group. Receiving it back via the group actor's Announce stream is that assurance, it confirms the Commit is in the group actor's outbox and was the first to arrive for this epoch. Until that echo-back arrives, the client has no such assurance and must not apply.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe client workflow:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003eGenerate Commit, send to group actor, do \u003cstrong\u003enot\u003c/strong\u003e apply locally yet\u003c/li\u003e\n\u003cli\u003eWatch the Announce stream:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eOwn Commit arrives first → confirmed winner, apply it, advance epoch\u003c/li\u003e\n\u003cli\u003eA competing Commit arrives first → discard pending Commit, apply the received one, re-propose if needed\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eThe group actor forwards everything blindly in arrival order; clients use the ordered Announce stream to determine the winner. Together they eliminate the irrecoverable race without the group actor needing any MLS knowledge.\u003c/p\u003e\n\u003ch2 dir=\"auto\"\u003eTwo proposed changes\u003c/h2\u003e\n\u003cp dir=\"auto\"\u003eThis proposal bundles two distinct changes:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003e1. Infrastructure: group actor as AP-level sequencer\u003c/strong\u003e\u003cbr\u003e\nA Group actor on the origin server provides a single inbox for all group MLS traffic and distributes an ordered Announce stream to all members. This is the delivery ordering mechanism, also described in \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"4397863233\" data-permission-text=\"Title is private\" data-url=\"https://github.com/swicg/activitypub-e2ee/issues/83\" data-hovercard-type=\"issue\" data-hovercard-url=\"/swicg/activitypub-e2ee/issues/83/hovercard\" href=\"https://github.com/swicg/activitypub-e2ee/issues/83\"\u003e#83\u003c/a\u003e (options C and D1).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003e2. Client protocol change: apply Commits on receive, not on generation\u003c/strong\u003e\u003cbr\u003e\nCurrently, MLS-over-AP clients (including our implementation) apply a Commit immediately upon generating it. This proposal requires clients to instead hold the Commit in a pending state and apply it only when it arrives back via the authoritative channel (the group actor's Announce stream). This is the behavioral change that makes ordering guarantees meaningful, without it, the group actor's total order is irrelevant because clients have already diverged.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIt also implies that potentially \u003cstrong\u003eany\u003c/strong\u003e ordered delivery channel (not only a group actor) could provide the same safety property, if clients adopt this behavior.\u003c/p\u003e\n\u003ch2 dir=\"auto\"\u003eTradeoffs\u003c/h2\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable role=\"table\"\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e\u003c/th\u003e\n\u003cth\u003eTimer-based P2P (current)\u003c/th\u003e\n\u003cth\u003eGroup actor hub\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eCommit ordering\u003c/td\u003e\n\u003ctd\u003eTimer stagger, fragile\u003c/td\u003e\n\u003ctd\u003eTotal order via inbox\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSelf-removal latency\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"notranslate\"\u003eleafIndex × 2s\u003c/code\u003e + co-device window\u003c/td\u003e\n\u003ctd\u003eNear-instant (first committer wins deterministically)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSingle point of failure\u003c/td\u003e\n\u003ctd\u003eNone\u003c/td\u003e\n\u003ctd\u003eGroup actor's server\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ePrivacy\u003c/td\u003e\n\u003ctd\u003eEach server sees full member list (can be mitigated by \u003ccode class=\"notranslate\"\u003ebto\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003eHub sees server-level topology only (if using option D1)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eInfrastructure required\u003c/td\u003e\n\u003ctd\u003eNone\u003c/td\u003e\n\u003ctd\u003eGroup actor support (FEP-1b12)\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003ch2 dir=\"auto\"\u003eRelationship to \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"4397863233\" data-permission-text=\"Title is private\" data-url=\"https://github.com/swicg/activitypub-e2ee/issues/83\" data-hovercard-type=\"issue\" data-hovercard-url=\"/swicg/activitypub-e2ee/issues/83/hovercard\" href=\"https://github.com/swicg/activitypub-e2ee/issues/83\"\u003e#83\u003c/a\u003e\u003c/h2\u003e\n\u003cp dir=\"auto\"\u003eThe same Group actor infrastructure that mitigates membership metadata exposure (Options C and D1 in \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"4397863233\" data-permission-text=\"Title is private\" data-url=\"https://github.com/swicg/activitypub-e2ee/issues/83\" data-hovercard-type=\"issue\" data-hovercard-url=\"/swicg/activitypub-e2ee/issues/83/hovercard\" href=\"https://github.com/swicg/activitypub-e2ee/issues/83\"\u003e#83\u003c/a\u003e) can also solve these MLS coordination problems. Implementing a group actor hub gives both privacy and ordering benefits with a single new infrastructure component.\u003c/p\u003e\n\u003ch2 dir=\"auto\"\u003eOpen questions\u003c/h2\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIs there interest in speccing the group actor as MLS coordination layer?\u003c/li\u003e\n\u003cli\u003eShould the group actor be a \u003cem\u003erequired\u003c/em\u003e component for federated MLS groups, or remain optional with P2P timer-based fallback?\u003c/li\u003e\n\u003cli\u003eDoes the inbox-ordering guarantee hold across all AP server implementations, or do we need an explicit sequence number on activities?\u003c/li\u003e\n\u003cli\u003eIf the group \u003cem\u003ecreator\u003c/em\u003e leaves the group, the sequencer itself can continue to function as long as the origin server accepts to keep the group running.\u003c/li\u003e\n\u003cli\u003eIf the group actor's server goes offline, the group loses its sequencer entirely, and no new messages can be ordered or delivered. This is a critical reliability and sustainability concern. Supporting \u003ccode class=\"notranslate\"\u003eMove\u003c/code\u003e activity on groups can help, at least for planned server sun-setting.\u003c/li\u003e\n\u003c/ul\u003e","bodyVersion":"ea993a85a37f4aca16a1e77fc74d738e5b7e87d8469024787e2e968ca96be4df","viewerCanUpdate":false,"url":"https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-4396216497","createdAt":"2026-05-07T10:14:27Z","authorAssociation":"NONE","viewerCanDelete":false,"viewerCanMinimize":false,"viewerCanUnminimize":false,"viewerCanReport":false,"viewerCanReportToMaintainer":false,"viewerCanBlockFromOrg":false,"viewerCanUnblockFromOrg":false,"viewerCanPin":false,"viewerCanUnpin":false,"viaApp":null,"isHidden":false,"minimizedReason":null,"showSpammyBadge":false,"createdViaEmail":false,"authorToRepoOwnerSponsorship":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","owner":{"__typename":"Organization","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx","login":"swicg","url":"https://github.com/swicg"},"isPrivate":false,"slashCommandsEnabled":false,"nameWithOwner":"swicg/activitypub-e2ee","databaseId":804531295},"__isComment":"IssueComment","viewerCanReadUserContentEdits":true,"lastEditedAt":"2026-05-07T10:22:59Z","lastUserContentEdit":{"editor":{"__typename":"User","url":"https://github.com/mayel","login":"mayel","id":"MDQ6VXNlcjExNTMxOA=="},"id":"UCE_lALOL_QsX88AAAABBgjwsc64aAS1"},"pinnedBy":null,"__isReactable":"IssueComment","reactionGroups":[{"content":"THUMBS_UP","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"THUMBS_DOWN","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"LAUGH","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HOORAY","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"CONFUSED","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HEART","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"ROCKET","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"EYES","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}}],"__isNode":"IssueComment"},"cursor":"Y3Vyc29yOnYyOpPPAAABngHue7gAqjQzOTYyMTY0OTc="},{"node":{"__typename":"CrossReferencedEvent","__isIssueTimelineItems":"CrossReferencedEvent","__isTimelineEvent":"CrossReferencedEvent","databaseId":6445240169,"createdAt":"2026-05-07T10:18:32Z","actor":{"__typename":"User","login":"mayel","id":"MDQ6VXNlcjExNTMxOA==","__isActor":"User","avatarUrl":"https://avatars.githubusercontent.com/u/115318?s=64\u0026u=4f2952ec42029ef082f2df76560bfc0b7e1e5ab4\u0026v=4","profileResourcePath":"/mayel","name":"Mayel de Borniol"},"source":{"__typename":"Issue","__isNode":"Issue","id":"I_kwDOL_QsX88AAAABBEaQ4g"},"willCloseTarget":false,"referencedAt":"2026-05-07T10:18:31Z","innerSource":{"__typename":"Issue","__isReferencedSubject":"Issue","id":"I_kwDOL_QsX88AAAABBEaQ4g","issueTitleHTML":"\"Remove Self\" from group","url":"https://github.com/swicg/activitypub-e2ee/issues/80","number":80,"stateReason":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","isPrivate":false,"owner":{"__typename":"Organization","login":"swicg","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx"}},"__isNode":"Issue"},"__isNode":"CrossReferencedEvent","id":"CRE_kwDOL_QsX88AAAABgCqPaQ"},"cursor":"Y3Vyc29yOnYyOpPPAAABngHyOMACqjY0NDUyNDAxNjk="},{"node":{"__typename":"CrossReferencedEvent","__isIssueTimelineItems":"CrossReferencedEvent","__isTimelineEvent":"CrossReferencedEvent","databaseId":6449572231,"createdAt":"2026-05-07T14:20:40Z","actor":{"__typename":"User","login":"mayel","id":"MDQ6VXNlcjExNTMxOA==","__isActor":"User","avatarUrl":"https://avatars.githubusercontent.com/u/115318?s=64\u0026u=4f2952ec42029ef082f2df76560bfc0b7e1e5ab4\u0026v=4","profileResourcePath":"/mayel","name":"Mayel de Borniol"},"source":{"__typename":"Issue","__isNode":"Issue","id":"I_kwDOL_QsX88AAAABBW9V6g"},"willCloseTarget":false,"referencedAt":"2026-05-07T14:20:39Z","innerSource":{"__typename":"Issue","__isReferencedSubject":"Issue","id":"I_kwDOL_QsX88AAAABBW9V6g","issueTitleHTML":"Agenda 26 May 2026","url":"https://github.com/swicg/activitypub-e2ee/issues/82","number":82,"stateReason":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","isPrivate":false,"owner":{"__typename":"Organization","login":"swicg","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx"}},"__isNode":"Issue"},"__isNode":"CrossReferencedEvent","id":"CRE_kwDOL_QsX88AAAABgGyphw"},"cursor":"Y3Vyc29yOnYyOpPPAAABngLP5sACqjY0NDk1NzIyMzE="},{"node":{"__typename":"IssueComment","__isIssueTimelineItems":"IssueComment","databaseId":4398091174,"viewerDidAuthor":false,"issue":{"author":{"__typename":"User","login":"evanp","id":"MDQ6VXNlcjY3NzA="},"id":"I_kwDOL_QsX87iGb3t","number":56,"locked":false,"databaseId":3793337837},"author":{"__typename":"User","login":"evanp","avatarUrl":"https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e\u0026v=4","profileUrl":"https://github.com/evanp","id":"MDQ6VXNlcjY3NzA=","name":"Evan Prodromou"},"id":"IC_kwDOL_QsX88AAAABBiWLpg","body":"We have two solutions to do:\n\n1. Conversation/context thread managed by the group initiator. Depends on a pull mechanism by the clients to confirm ordering.\n2. Group actor that announces the content, adding some activity ordering.\n\n","bodyHTML":"\u003cp dir=\"auto\"\u003eWe have two solutions to do:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003eConversation/context thread managed by the group initiator. Depends on a pull mechanism by the clients to confirm ordering.\u003c/li\u003e\n\u003cli\u003eGroup actor that announces the content, adding some activity ordering.\u003c/li\u003e\n\u003c/ol\u003e","bodyVersion":"1b532290ad9545c1c92b9ea106fae75036c708e429cae53706659571a7d2915a","viewerCanUpdate":false,"url":"https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-4398091174","createdAt":"2026-05-07T14:39:36Z","authorAssociation":"COLLABORATOR","viewerCanDelete":false,"viewerCanMinimize":false,"viewerCanUnminimize":false,"viewerCanReport":false,"viewerCanReportToMaintainer":false,"viewerCanBlockFromOrg":false,"viewerCanUnblockFromOrg":false,"viewerCanPin":false,"viewerCanUnpin":false,"viaApp":null,"isHidden":false,"minimizedReason":null,"showSpammyBadge":false,"createdViaEmail":false,"authorToRepoOwnerSponsorship":null,"repository":{"id":"R_kgDOL_QsXw","name":"activitypub-e2ee","owner":{"__typename":"Organization","id":"MDEyOk9yZ2FuaXphdGlvbjIzNTYwOTcx","login":"swicg","url":"https://github.com/swicg"},"isPrivate":false,"slashCommandsEnabled":false,"nameWithOwner":"swicg/activitypub-e2ee","databaseId":804531295},"__isComment":"IssueComment","viewerCanReadUserContentEdits":true,"lastEditedAt":null,"lastUserContentEdit":null,"pinnedBy":null,"__isReactable":"IssueComment","reactionGroups":[{"content":"THUMBS_UP","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"THUMBS_DOWN","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"LAUGH","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HOORAY","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"CONFUSED","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"HEART","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"ROCKET","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}},{"content":"EYES","viewerHasReacted":false,"reactors":{"totalCount":0,"nodes":[]}}],"__isNode":"IssueComment"},"cursor":"Y3Vyc29yOnYyOpPPAAABngLhPEAAqjQzOTgwOTExNzQ="}]},"backTimelineItems":{"pageInfo":{"hasPreviousPage":true,"startCursor":null},"totalCount":13,"edges":[]}}},"safeViewer":null}},"timestamp":1778277985}]},"title":"Issue","appPayload":{"initial_view_content":{"can_edit_view":true},"current_user":null,"current_user_settings":{"preferred_emoji_skin_tone":null,"copilot_show_functionality":false,"use_single_key_shortcut":false},"paste_url_link_as_plain_text":false,"base_avatar_url":"https://avatars.githubusercontent.com","help_url":"https://docs.github.com","sso_organizations":null,"current_sso_orgs_match_dismissed_cookie":null,"multi_tenant":false,"tracing":false,"tracing_flamegraph":false,"catalog_service":"github/issues","scoped_repository":{"id":"R_kgDOL_QsXw","owner":"swicg","name":"activitypub-e2ee","is_archived":false,"has_projects_enabled":true},"best_match_sort_enabled":false,"tabbed_timeline":false,"transactionalMessageBanner":null,"enabled_features":{"use_pull_request_subscriptions_enabled":false,"pull_request_single_subscription":true,"disable_issues_react_ssr":false,"copilot_natural_language_github_search":false,"private_avatars":false,"reserved_domain":true,"projects_classic_sunset_override":false,"notifyd_issue_watch_activity_notify":false,"notifyd_enable_issue_thread_subscriptions":false,"timeline_best_effort_count_optimization":false,"copilot_auto_assign_metadata":false,"copilot_workspace_cross_repo_selection":false,"copilot_agent_mode":false,"issues_react_force_turbo_nav":false,"issues_react_client_side_caching":false,"copilot_swe_agent":false,"react_version_mismatch_detection":false,"issues_react_graceful_not_found_handling":false,"issue_create_relationships":false,"milestone_closed_issues_prioritization":true,"issues_react_timeline_tabs":false,"issues_search_type_gql":true,"issue_releases_sidebar":true,"tasklist_block":false,"issues_react_perf_test":false,"issue_pinned_views":false,"issues_triage_agent_enrolled":false,"issues_triage_agent_config_editor":true,"issues_create_semantic_similarity_analytics":false,"semantic_similarity_duplicate_issue_detection":false,"issue_cca_visualization":false}}}</script>
<div data-target="react-app.reactRoot"><link rel="preload" as="image" href="https://avatars.githubusercontent.com/u/6770?s=64&amp;u=85e683e6edf44982a2d847e6bb28c63a53fbc43e&amp;v=4"/><link rel="preload" as="image" href="https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e&amp;v=4&amp;size=80"/><link rel="preload" as="image" href="https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e&amp;v=4&amp;size=48"/><!--$--><!--$--><div class="IssueShowPage-module__issueDetailContainer__DbXfA"><div class="primary-viewer IssueDetail-module__IssueDetailContainer__JnqVq" data-testid="issue-viewer-container"><!--$--><div class="IssueViewer-module__issueViewerContainer__Hualk IssueViewer-module__mainContainer__lmFuF"><!--$--><div class="ContentWrapper-module__contentContainer__H47cS"><div aria-label="Header" role="region" data-testid="issue-header" class="HeaderViewer-module__headerRegion__hrG_B"><div class="prc-PageHeader-PageHeader-YLwBQ HeaderViewer-module__headerContainer__lIELq "><div class="prc-PageHeader-TitleArea-2n2J0 HeaderViewer-module__PageHeader_TitleArea__gvcTw" data-component="TitleArea" data-size-variant="medium"><h1 class="prc-PageHeader-Title-p0Mgh HeaderViewer-module__PageHeader_Title__jVJ0i HeaderViewer-module__PageHeader_Title_viewport__r6rl8 HeaderViewer-module__PageHeader_Title_marginRight__S6GLh prc-Heading-Heading-MtWFE" data-component="PH_Title" data-hidden="false"><bdi class="markdown-title HeaderViewer-module__issueTitle__DW72_" data-testid="issue-title">Maintaining ordering in the group conversation</bdi> <span class="HeaderViewer-module__issueNumberText__MEUhM">#56</span></h1></div><div class="prc-PageHeader-ContextArea-ueeWv" data-hidden-regular="true"><div class="prc-PageHeader-ContextAreaActions-DLQP5 HeaderViewer-module__PageHeader_ContextAreaActions__xYSsx" data-hidden-regular="true"><div class="HeaderMenu-module__menuActionsContainer__K0Mga"><div class="HeaderMenu-module__buttonContainer__S3hWB HeaderMenu-module__buttonContainer_viewport__Q3rwe"><!--$!--><template></template><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="primary"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">New issue</span></span></button><!--/$--></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_25oktb_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardButton-module__tooltip__BhMvU prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy link" aria-hidden="true" id="_R_25oktb_">Copy link</span></div></div></div><div class="prc-PageHeader-Actions-wawWm HeaderViewer-module__PageHeader_Actions___iosX HeaderViewer-module__PageHeader_Actions_viewport__o4PW1" data-component="PH_Actions"><div class="HeaderMenu-module__menuActionsContainer__K0Mga"><div class="HeaderMenu-module__buttonContainer__S3hWB HeaderMenu-module__buttonContainer_viewport__Q3rwe"><!--$!--><template></template><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="primary"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">New issue</span></span></button><!--/$--></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_29oktb_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardButton-module__tooltip__BhMvU prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy link" aria-hidden="true" id="_R_29oktb_">Copy link</span></div></div></div></div></div><div class="ContentWrapper-module__contentContainer__H47cS"><div data-testid="issue-metadata-fixed" class="HeaderMetadata-module__metadataContainer__RYoai"><div class="HeaderMetadata-module__metadataBorder__vMRcF"><div class="HeaderMetadata-module__metadataContent__Dg2N7"><div><span data-testid="header-state" class="prc-StateLabel-StateLabel-Iawzp HeaderState-module__stateLabel__vlM4W" data-size="medium" data-status="issueOpened"><svg data-component="Octicon" focusable="false" aria-label="Issue" class="octicon octicon-issue-opened prc-StateLabel-Icon-YICrR" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg>Open</span></div><!--$--><!--/$--></div></div></div></div><div data-testid="issue-metadata-sticky" id="issue-viewer-sticky-header" class="HeaderMetadata-module__stickyContainer__XEec_ HeaderMetadata-module__stickyContainerHidden__DJzgH"><div class="ContentWrapper-module__contentContainer__H47cS"><div class="HeaderMetadata-module__stickyContent__ljPb0"><div><span data-testid="header-state" class="prc-StateLabel-StateLabel-Iawzp HeaderState-module__stateLabel__vlM4W" data-size="medium" data-status="issueOpened"><svg data-component="Octicon" focusable="false" aria-label="Issue" class="octicon octicon-issue-opened prc-StateLabel-Icon-YICrR" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg>Open</span></div><div class="HeaderMetadata-module__titleAndMetadata__yKAq3"><div class="StickyHeaderTitle-module__stickyTitleContainer__xkM7n"><a class="StickyHeaderTitle-module__stickyTitleLink__H7P2k prc-Link-Link-9ZwDx" data-component="Link" href="#top"><bdi class="markdown-title" data-testid="issue-title-sticky">Maintaining ordering in the group conversation</bdi></a><span class="StickyHeaderTitle-module__issueNumberText__k2kX0">#56</span></div><div class="HeaderMetadata-module__smallMetadataRow__Bvi2e HeaderMetadata-module__smallMetadataRow_viewport__j8aKB"><!--$--><!--/$--></div></div><div><div class="HeaderMenu-module__menuActionsContainer__K0Mga"><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_3p4tb_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardButton-module__tooltip__BhMvU prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy link" aria-hidden="true" id="_R_3p4tb_">Copy link</span></div></div></div></div></div><div class="ContentWrapper-module__contentContainer__H47cS"><div class="IssueMetadata-module__issueMetadata__ph4wO"><div class="IssueMetadata-module__metadata__y840P"><div class="IssueMetadata-module__metadataTitle__mIZQ2">Assignees</div><div class="IssueMetadata-module__metadataValue__VpFzn"><span data-component="AvatarStack" data-variant="cascade" data-shape="circle" data-avatar-count="1" data-responsive="" class="pc-AvatarStack--variant pc-AvatarStack--shape AssigneesMetadata-module__avatarStack__recCY prc-AvatarStack-AvatarStack-vkIK2" style="--stackSize-narrow:20px;--stackSize-regular:20px;--stackSize-wide:20px"><div data-component="AvatarStack.Body" class="pc-AvatarStackBody prc-AvatarStack-AvatarStackBody-JFK4u" tabindex="0"> <a class="prc-Link-Link-9ZwDx" data-component="Link" aria-label="evanp is assigned" href="/evanp"><img data-component="Avatar" class="AssigneesMetadata-module__avatar__SdD12 prc-Avatar-Avatar-0xaUi" alt="evanp" width="20" height="20" style="--avatarSize-regular:20px" src="https://avatars.githubusercontent.com/u/6770?s=64&amp;u=85e683e6edf44982a2d847e6bb28c63a53fbc43e&amp;v=4" data-testid="github-avatar"/></a></div></span></div></div></div></div><div class="Header-module__stickyObservableBox__nsRWC"></div><div class="Header-module__HeaderContentWrapper__pFwre"><div class="ContentWrapper-module__contentContainer__H47cS"><div class="Header-module__headerSpacer__CmNnw"></div></div></div><div class="ContentWrapper-module__contentContainer__H47cS"><div class="IssueViewer-module__contentAndSidebarWrapper__jEPzb IssueViewer-module__contentAndSidebarWrapper_viewport__psC8n"><div class="IssueViewer-module__contentArea__ChMIU IssueViewer-module__contentArea_viewport__xcHZT"><div data-testid="issue-viewer-issue-container"><div class="IssueBody-module__outerContainer__ULNTb"><a class="Avatar-module__avatarLink__LpV3I Avatar-module__avatarOuter__oECIk prc-Link-Link-9ZwDx" data-component="Link" href="https://github.com/evanp" aria-label="@evanp&#x27;s profile"><img data-component="Avatar" class="Avatar-module__issueViewerAvatar__BECCA prc-Avatar-Avatar-0xaUi" alt="@evanp" width="40" height="40" style="--avatarSize-regular:40px" src="https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e&amp;v=4&amp;size=80" data-testid="github-avatar"/></a><div data-testid="issue-body" class="react-issue-body IssueBody-module__innerContainer__yRKH5" data-hpc="true"><h2 class="sr-only">Description</h2><div class="IssueBody-module__headerRow__sH4dg"><div class="IssueBody-module__commentBorder__U9VPv"><div class="IssueBodyHeader-module__IssueBodyHeaderContainer__SrDB7 IssueBodyHeader-module__viewerDidNotAuthor__vD8tZ"><div class="ActivityHeader-module__activityHeader__ZGlyB IssueBodyHeader-module__activityHeaderWrapper__nrxjr"><div class="Avatar-module__avatarInner__uWzS0 IssueBodyHeader-module__avatarContainer__O8TC2"><a class="Avatar-module__avatarLink__LpV3I prc-Link-Link-9ZwDx" data-component="Link" href="https://github.com/evanp" aria-label="@evanp&#x27;s profile"><img data-component="Avatar" class="prc-Avatar-Avatar-0xaUi" alt="@evanp" width="24" height="24" style="--avatarSize-regular:24px" src="https://avatars.githubusercontent.com/u/6770?u=85e683e6edf44982a2d847e6bb28c63a53fbc43e&amp;v=4&amp;size=48" data-testid="github-avatar"/></a></div><div class="ActivityHeader-module__narrowViewportWrapper__n_VAC IssueBodyHeader-module__narrowViewportWrapper__iLs_y"><div class="IssueBodyHeader-module__titleSection__dX9cz"><a class="IssueBodyHeaderAuthor-module__authorLoginLink__aTls_ prc-Link-Link-9ZwDx" data-component="Link" href="https://github.com/evanp" data-testid="issue-body-header-author">evanp</a></div><div class="ActivityHeader-module__footer__HD8mP IssueBodyHeader-module__footerSection__Df7HB"><span>opened </span><a class="IssueBodyHeader-module__dateLink__kYTxQ prc-Link-Link-9ZwDx" data-component="Link" href="https://github.com/swicg/activitypub-e2ee/issues/56#issue-3793337837" data-testid="issue-body-header-link"><relative-time class="IssueBodyHeader-module__RelativeTime__xv0lw">on <!-- -->Jan 8, 2026</relative-time></a></div></div><div class="ActivityHeader-module__narrowViewportWrapper__n_VAC IssueBodyHeader-module__actionsWrapper__D4Syp"><div class="ActivityHeader-module__edits__pnYtu IssueBodyHeader-module__editsSection__nQnXE"></div><div class="IssueBodyHeader-module__badgesSection___PWtJ"><div class="IssueBodyHeader-module__badgeGroup__EPYnd"></div><div class="IssueBodyHeader-module__actionsSection__gnoaX"><button data-component="IconButton" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_v5bd2mtb_" id="_R_15bd2mtb_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-hidden="true" id="_R_v5bd2mtb_">Issue body actions</span></div></div></div></div></div><div class="IssueBodyViewer-module__IssueBody__xbjV0" id="issue-body-viewer" data-testid="issue-body-viewer"><div data-testid="markdown-body" data-team-hovercards-enabled="true" class="markdown-body" data-turbolinks="false"><div class="markdown-body NewMarkdownViewer-module__safe-html-box__ZT1eD"><p dir="auto">Ordering is very important in MLS. We need to have a way to have an official ordering.</p></div></div><div class="IssueBodyViewer-module__IssueBodyTaskList__a_Inr"><!--$!--><template></template><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ReactionViewerAnchor-module__ReactionViewerAnchorButton__TujhO prc-Button-IconButton-fyge7" data-inactive="true" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_el2mtb_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-smiley" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm3.82 1.636a.75.75 0 0 1 1.038.175l.007.009c.103.118.22.222.35.31.264.178.683.37 1.285.37.602 0 1.02-.192 1.285-.371.13-.088.247-.192.35-.31l.007-.008a.75.75 0 0 1 1.222.87l-.022-.015c.02.013.021.015.021.015v.001l-.001.002-.002.003-.005.007-.014.019a2.066 2.066 0 0 1-.184.213c-.16.166-.338.316-.53.445-.63.418-1.37.638-2.127.629-.946 0-1.652-.308-2.126-.63a3.331 3.331 0 0 1-.715-.657l-.014-.02-.005-.006-.002-.003v-.002h-.001l.613-.432-.614.43a.75.75 0 0 1 .183-1.044ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM5 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm5.25 2.25.592.416a97.71 97.71 0 0 0-.592-.416Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-hidden="true" id="_R_el2mtb_">Reactions are currently unavailable</span><!--/$--></div></div></div></div></div></div></div><div data-testid="issue-viewer-comments-container" class="react-comments-container"><div class="IssueViewer-module__commentsContainer__qDkcR"><!--$!--><template></template><div class="issue-timeline-loading-module__delaySkeletonLoad__jSGd5" data-testid="issue-timeline-loading"><div><div class="CommentLoading-module__CommentLoadingContainer__sM4lf"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__elliptical__Dkk2i CommentLoading-module__avatarSkeleton__SULiu" style="width:40px;height:40px"></div><div class="CommentLoading-module__CommentLoadingContentWrapper__N0UXI"><div class="CommentDivider-module__CommentDividerContainer__yjzmV"><div class="CommentDivider-module__CommentDividerLeftLine__eqHQu CommentDivider-module__paddingBottomDefault__pzmHv"></div><div class="CommentDivider-module__CommentDividerRightLine__VJuKh CommentDivider-module__paddingBottomDefault__pzmHv"></div></div><div data-testid="comment-skeleton" class="CommentLoading-module__CommentLoadingCard__HkqV6"><div class="CommentLoading-module__CommentLoadingHeader__kHKXi"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:150px"></div></div><div class="CommentLoading-module__CommentLoadingContent__u2TbG"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:57%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:75%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:76%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:60%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:40%"></div></div></div></div></div></div><div><div class="CommentLoading-module__CommentLoadingContainer__sM4lf"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__elliptical__Dkk2i CommentLoading-module__avatarSkeleton__SULiu" style="width:40px;height:40px"></div><div class="CommentLoading-module__CommentLoadingContentWrapper__N0UXI"><div class="CommentDivider-module__CommentDividerContainer__yjzmV"><div class="CommentDivider-module__CommentDividerLeftLine__eqHQu CommentDivider-module__paddingBottomDefault__pzmHv"></div><div class="CommentDivider-module__CommentDividerRightLine__VJuKh CommentDivider-module__paddingBottomDefault__pzmHv"></div></div><div data-testid="comment-skeleton" class="CommentLoading-module__CommentLoadingCard__HkqV6"><div class="CommentLoading-module__CommentLoadingHeader__kHKXi"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:150px"></div></div><div class="CommentLoading-module__CommentLoadingContent__u2TbG"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:75%"></div></div></div></div></div></div><div><div class="CommentLoading-module__CommentLoadingContainer__sM4lf"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__elliptical__Dkk2i CommentLoading-module__avatarSkeleton__SULiu" style="width:40px;height:40px"></div><div class="CommentLoading-module__CommentLoadingContentWrapper__N0UXI"><div class="CommentDivider-module__CommentDividerContainer__yjzmV"><div class="CommentDivider-module__CommentDividerLeftLine__eqHQu CommentDivider-module__paddingBottomDefault__pzmHv"></div><div class="CommentDivider-module__CommentDividerRightLine__VJuKh CommentDivider-module__paddingBottomDefault__pzmHv"></div></div><div data-testid="comment-skeleton" class="CommentLoading-module__CommentLoadingCard__HkqV6"><div class="CommentLoading-module__CommentLoadingHeader__kHKXi"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:150px"></div></div><div class="CommentLoading-module__CommentLoadingContent__u2TbG"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:76%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:60%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:54%"></div></div></div></div></div></div><div><div class="CommentLoading-module__CommentLoadingContainer__sM4lf"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__elliptical__Dkk2i CommentLoading-module__avatarSkeleton__SULiu" style="width:40px;height:40px"></div><div class="CommentLoading-module__CommentLoadingContentWrapper__N0UXI"><div class="CommentDivider-module__CommentDividerContainer__yjzmV"><div class="CommentDivider-module__CommentDividerLeftLine__eqHQu CommentDivider-module__paddingBottomDefault__pzmHv"></div><div class="CommentDivider-module__CommentDividerRightLine__VJuKh CommentDivider-module__paddingBottomDefault__pzmHv"></div></div><div data-testid="comment-skeleton" class="CommentLoading-module__CommentLoadingCard__HkqV6"><div class="CommentLoading-module__CommentLoadingHeader__kHKXi"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:150px"></div></div><div class="CommentLoading-module__CommentLoadingContent__u2TbG"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:60%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:54%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:57%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:75%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:45%"></div></div></div></div></div></div><div><div class="CommentLoading-module__CommentLoadingContainer__sM4lf"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__elliptical__Dkk2i CommentLoading-module__avatarSkeleton__SULiu" style="width:40px;height:40px"></div><div class="CommentLoading-module__CommentLoadingContentWrapper__N0UXI"><div class="CommentDivider-module__CommentDividerContainer__yjzmV"><div class="CommentDivider-module__CommentDividerLeftLine__eqHQu CommentDivider-module__paddingBottomDefault__pzmHv"></div><div class="CommentDivider-module__CommentDividerRightLine__VJuKh CommentDivider-module__paddingBottomDefault__pzmHv"></div></div><div data-testid="comment-skeleton" class="CommentLoading-module__CommentLoadingCard__HkqV6"><div class="CommentLoading-module__CommentLoadingHeader__kHKXi"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:150px"></div></div><div class="CommentLoading-module__CommentLoadingContent__u2TbG"><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:54%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:57%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:75%"></div><div class="LoadingSkeleton-module__skeleton__euqGn LoadingSkeleton-module__rounded__J10DA LoadingSkeleton-module__heightSm__YvOXy" style="width:76%"></div></div></div></div></div></div></div><!--/$--></div></div></div><div data-testid="issue-viewer-metadata-container" class="IssueViewer-module__metadataSidebar__GxfUH IssueViewer-module__metadataSidebar_viewport__AKkg5"><div class="IssueViewer-module__issueViewerMetadataPane__bXvwI" data-testid="issue-viewer-metadata-pane"><h2 class="IssueViewer-module__metadataHeader__UQJId prc-Heading-Heading-MtWFE">Metadata</h2><h2 class="IssueViewer-module__largeScreenMetadataHeader__iySgH sr-only prc-Heading-Heading-MtWFE">Metadata</h2><div data-testid="sticky-sidebar"><div class="IssueSidebar-module__sidebarContent__HKaGK"><div data-testid="sidebar-assignees-section" class="Section-module__SectionContainer__DFzgf"><div class="Section-module__headerContentWrapper__gjSPk"><div class="SectionHeader-module__containerReadonly__QwNSM"><h3 class="SectionHeader-module__SectionHeaderTitle__qcG5P SectionHeader-module__headingReadonly__Xl5Sa prc-Heading-Heading-MtWFE">Assignees</h3></div></div><div class="Section-module__childrenContainer__tpT2L"><ul class="prc-ActionList-ActionList-rPFF2 Assignees-module__assigneesList__ZKD6F" data-component="ActionList" data-dividers="false" data-variant="full" data-icv-visible="true"><li data-component="ActionList.Item" data-has-description="false" class="prc-ActionList-ActionListItem-So4vC"><a class="prc-ActionList-ActionListContent-KBb8- prc-Link-Link-9ZwDx" data-component="Link" tabindex="0" aria-labelledby="_R_7b4f6tb_--label" id="_R_7b4f6tb_" data-size="medium" href="/evanp" target="_blank" data-hovercard-url="/users/evanp/hovercard" data-hovercard-type="user" aria-keyshortcuts="Alt+ArrowUp" octo-click="hovercard-link-click" octo-dimensions="link_type:self"><span class="prc-ActionList-Spacer-4tR2m"></span><span class="prc-ActionList-LeadingVisual-NBr28 prc-ActionList-VisualWrap-bdCsS" data-component="ActionList.LeadingVisual"><img data-component="Avatar" class="prc-Avatar-Avatar-0xaUi" alt="@evanp" width="20" height="20" style="--avatarSize-regular:20px" src="https://avatars.githubusercontent.com/u/6770?s=64&amp;u=85e683e6edf44982a2d847e6bb28c63a53fbc43e&amp;v=4" data-testid="github-avatar"/></span><span class="prc-ActionList-ActionListSubContent-gKsFp" data-component="ActionList.Item--DividerContainer"><span id="_R_7b4f6tb_--label" class="prc-ActionList-ItemLabel-81ohH" data-component="ActionList.Item.Label"><div data-testid="issue-assignees" class="Assignees-module__assigneeNameLabel__RULR6">evanp</div></span></span></a></li></ul></div></div><div data-testid="sidebar-labels-section" class="Section-module__SectionContainer__DFzgf"><div class="Section-module__headerContentWrapper__gjSPk"><div class="SectionHeader-module__containerReadonly__QwNSM"><h3 class="SectionHeader-module__SectionHeaderTitle__qcG5P SectionHeader-module__headingReadonly__Xl5Sa prc-Heading-Heading-MtWFE">Labels</h3></div><span class="Section-module__emptyText__P72MM">No labels</span><div class="Section-module__hiddenChildrenContainer__MgzXj"><div tabindex="-1" data-testid="issue-labels" class="LabelsList-module__labelsListContainer__q43kf">No labels</div></div></div></div><div data-testid="sidebar-types-section" class="Section-module__SectionContainer__DFzgf"><div class="Section-module__headerContentWrapper__gjSPk"><div class="SectionHeader-module__containerReadonly__QwNSM"><h3 class="SectionHeader-module__SectionHeaderTitle__qcG5P SectionHeader-module__headingReadonly__Xl5Sa prc-Heading-Heading-MtWFE">Type</h3></div><span class="Section-module__emptyText__P72MM">No type</span><div class="Section-module__hiddenChildrenContainer__MgzXj"><div class="TypesSection-module__typeContainer__FnO03"><div class="IssueType-module__hiddenPlaceholder__Z7sTb"></div></div></div></div></div><!--$--><div data-testid="sidebar-projects-section" class="Section-module__SectionContainer__DFzgf"><div class="Section-module__headerContentWrapper__gjSPk"><div class="SectionHeader-module__containerReadonly__QwNSM"><h3 class="SectionHeader-module__SectionHeaderTitle__qcG5P SectionHeader-module__headingReadonly__Xl5Sa prc-Heading-Heading-MtWFE">Projects</h3></div><span class="Section-module__emptyText__P72MM">No projects</span><div class="Section-module__hiddenChildrenContainer__MgzXj"><div class="ProjectsSection-module__projectItemsContainer__D1nPN"></div></div></div></div><!--/$--><div data-testid="sidebar-milestones-section" class="Section-module__SectionContainer__DFzgf"><div class="Section-module__headerContentWrapper__gjSPk"><div class="SectionHeader-module__containerReadonly__QwNSM"><h3 class="SectionHeader-module__SectionHeaderTitle__qcG5P SectionHeader-module__headingReadonly__Xl5Sa prc-Heading-Heading-MtWFE">Milestone</h3></div><span class="Section-module__emptyText__P72MM">No milestone</span><div class="Section-module__hiddenChildrenContainer__MgzXj"><ul class="prc-ActionList-ActionList-rPFF2" data-component="ActionList" data-dividers="false" data-variant="full"><div class="Milestone-module__hiddenPlaceholder__jxVaN"></div></ul></div></div></div><!--$--><div data-testid="sidebar-section" class="Section-module__SectionContainer__DFzgf"><div class="Section-module__headerContentWrapper__gjSPk"><div class="SectionHeader-module__containerReadonly__QwNSM"><h3 class="SectionHeader-module__SectionHeaderTitle__qcG5P SectionHeader-module__headingReadonly__Xl5Sa prc-Heading-Heading-MtWFE">Relationships</h3></div><span class="Section-module__emptyText__P72MM">None yet</span><div class="Section-module__hiddenChildrenContainer__MgzXj"></div></div></div><div data-testid="sidebar-section" class="Section-module__SectionContainer__DFzgf"><div class="Section-module__headerContentWrapper__gjSPk"><div class="SectionHeader-module__containerReadonly__QwNSM"><h3 class="SectionHeader-module__SectionHeaderTitle__qcG5P SectionHeader-module__headingReadonly__Xl5Sa prc-Heading-Heading-MtWFE">Development</h3></div><span class="Section-module__emptyText__P72MM">No branches or pull requests</span><div class="Section-module__hiddenChildrenContainer__MgzXj"></div></div></div><!--/$--><h2 class="sr-only prc-Heading-Heading-MtWFE">Issue actions</h2><ul class="prc-ActionList-ActionList-rPFF2 OptionsSection-module__ActionListOverrides__e4GEe" data-component="ActionList" data-dividers="false" data-variant="full"></ul></div></div></div></div></div></div><!--/$--></div><!--/$--></div></div><!--/$--><!--/$--><script type="application/json" id="__PRIMER_DATA__R_0___">{"resolvedServerColorMode":"day"}</script></div>
</react-app>
</turbo-frame>
</div>
</turbo-frame>
</main>
</div>
</div>
<footer class="footer tmp-pt-7 tmp-pb-6 f6 color-fg-muted color-border-subtle p-responsive" role="contentinfo" >
<h2 class='sr-only'>Footer</h2>
<div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap">
<div class="d-flex flex-items-center flex-shrink-0 mx-2">
<a aria-label="GitHub Homepage" class="footer-octicon mr-2" href="https://github.com">
<svg aria-hidden="true" data-component="Octicon" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github">
<path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path>
</svg>
</a>
<span>
&copy; 2026 GitHub,&nbsp;Inc.
</span>
</div>
<nav aria-label="Footer">
<h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3>
<ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading">
<li class="mx-2">
<a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a>
</li>
<li class="mx-2">
<a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a>
</li>
<li class="mx-2">
<a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a>
</li>
<li class="mx-2">
<a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a>
</li>
<li class="mx-2">
<a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to community&quot;,&quot;label&quot;:&quot;text:community&quot;}" href="https://git.521000.bestmunity/" data-view-component="true" class="Link--secondary Link">Community</a>
</li>
<li class="mx-2">
<a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a>
</li>
<li class="mx-2">
<a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a>
</li>
<li class="mx-2" >
<cookie-consent-link>
<button
type="button"
class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent"
data-action="click:cookie-consent-link#showConsentManagement"
data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}"
>
Manage cookies
</button>
</cookie-consent-link>
</li>
<li class="mx-2">
<cookie-consent-link>
<button
type="button"
class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent text-left"
data-action="click:cookie-consent-link#showConsentManagement"
data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}"
>
Do not share my personal information
</button>
</cookie-consent-link>
</li>
</ul>
</nav>
</div>
</footer>
<ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999"
data-locale="en"
data-initial-cookie-consent-allowed=""
data-cookie-consent-required="true"
></ghcc-consent>
<div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden>
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
<path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
<button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button>
You can’t perform that action at this time.
</div>
<template id="site-details-dialog">
<details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open>
<summary role="button" aria-label="Close dialog"></summary>
<details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal">
<button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog>
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button>
<div class="octocat-spinner tmp-my-6 js-details-dialog-spinner"></div>
</details-dialog>
</details>
</template>
<div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;">
<div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;">
</div>
</div>
<template id="snippet-clipboard-copy-button">
<div class="zeroclipboard-container position-absolute right-0 top-0">
<clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2 tmp-m-2">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2 tmp-m-2">
<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
</clipboard-copy>
</div>
</template>
<template id="snippet-clipboard-copy-button-unpositioned">
<div class="zeroclipboard-container">
<clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w">
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
<svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none">
<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
</clipboard-copy>
</div>
</template>
</div>
<div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div>
<div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div>
</body>
</html>
{
"issue": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56",
"repository_url": "https://api.github.com/repos/swicg/activitypub-e2ee",
"labels_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56/labels{/name}",
"comments_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56/comments",
"events_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56/events",
"html_url": "https://github.com/swicg/activitypub-e2ee/issues/56",
"id": 3793337837,
"node_id": "I_kwDOL_QsX87iGb3t",
"number": 56,
"title": "Maintaining ordering in the group conversation",
"user": {
"login": "evanp",
"id": 6770,
"node_id": "MDQ6VXNlcjY3NzA=",
"avatar_url": "https://avatars.githubusercontent.com/u/6770?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/evanp",
"html_url": "https://github.com/evanp",
"followers_url": "https://api.github.com/users/evanp/followers",
"following_url": "https://api.github.com/users/evanp/following{/other_user}",
"gists_url": "https://api.github.com/users/evanp/gists{/gist_id}",
"starred_url": "https://api.github.com/users/evanp/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/evanp/subscriptions",
"organizations_url": "https://api.github.com/users/evanp/orgs",
"repos_url": "https://api.github.com/users/evanp/repos",
"events_url": "https://api.github.com/users/evanp/events{/privacy}",
"received_events_url": "https://api.github.com/users/evanp/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [],
"state": "open",
"locked": false,
"assignees": [
{
"login": "evanp",
"id": 6770,
"node_id": "MDQ6VXNlcjY3NzA=",
"avatar_url": "https://avatars.githubusercontent.com/u/6770?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/evanp",
"html_url": "https://github.com/evanp",
"followers_url": "https://api.github.com/users/evanp/followers",
"following_url": "https://api.github.com/users/evanp/following{/other_user}",
"gists_url": "https://api.github.com/users/evanp/gists{/gist_id}",
"starred_url": "https://api.github.com/users/evanp/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/evanp/subscriptions",
"organizations_url": "https://api.github.com/users/evanp/orgs",
"repos_url": "https://api.github.com/users/evanp/repos",
"events_url": "https://api.github.com/users/evanp/events{/privacy}",
"received_events_url": "https://api.github.com/users/evanp/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
}
],
"milestone": null,
"comments": 7,
"created_at": "2026-01-08T15:26:08Z",
"updated_at": "2026-05-07T14:39:36Z",
"closed_at": null,
"assignee": {
"login": "evanp",
"id": 6770,
"node_id": "MDQ6VXNlcjY3NzA=",
"avatar_url": "https://avatars.githubusercontent.com/u/6770?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/evanp",
"html_url": "https://github.com/evanp",
"followers_url": "https://api.github.com/users/evanp/followers",
"following_url": "https://api.github.com/users/evanp/following{/other_user}",
"gists_url": "https://api.github.com/users/evanp/gists{/gist_id}",
"starred_url": "https://api.github.com/users/evanp/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/evanp/subscriptions",
"organizations_url": "https://api.github.com/users/evanp/orgs",
"repos_url": "https://api.github.com/users/evanp/repos",
"events_url": "https://api.github.com/users/evanp/events{/privacy}",
"received_events_url": "https://api.github.com/users/evanp/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"author_association": "COLLABORATOR",
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "Ordering is very important in MLS. We need to have a way to have an official ordering.",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56/timeline",
"performed_via_github_app": null,
"state_reason": null,
"pinned_comment": null
},
"comments": [
{
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3724407041",
"html_url": "https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3724407041",
"issue_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56",
"id": 3724407041,
"node_id": "IC_kwDOL_QsX87d_fEB",
"user": {
"login": "evanp",
"id": 6770,
"node_id": "MDQ6VXNlcjY3NzA=",
"avatar_url": "https://avatars.githubusercontent.com/u/6770?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/evanp",
"html_url": "https://github.com/evanp",
"followers_url": "https://api.github.com/users/evanp/followers",
"following_url": "https://api.github.com/users/evanp/following{/other_user}",
"gists_url": "https://api.github.com/users/evanp/gists{/gist_id}",
"starred_url": "https://api.github.com/users/evanp/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/evanp/subscriptions",
"organizations_url": "https://api.github.com/users/evanp/orgs",
"repos_url": "https://api.github.com/users/evanp/repos",
"events_url": "https://api.github.com/users/evanp/events{/privacy}",
"received_events_url": "https://api.github.com/users/evanp/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created_at": "2026-01-08T15:32:24Z",
"updated_at": "2026-01-08T15:39:36Z",
"body": "One way to do this is with a collection that's maintained on the group initiator's server. Similar to the `thread` collection:\n\nhttps://codeberg.org/fediverse/fep/src/branch/main/fep/76ea/fep-76ea.md\n\n...however, the messages in the conversation aren't related with an `inReplyTo` property in MLS in ActivityPub.",
"author_association": "COLLABORATOR",
"pin": null,
"reactions": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3724407041/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"performed_via_github_app": null
},
{
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3724435190",
"html_url": "https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3724435190",
"issue_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56",
"id": 3724435190,
"node_id": "IC_kwDOL_QsX87d_l72",
"user": {
"login": "evanp",
"id": 6770,
"node_id": "MDQ6VXNlcjY3NzA=",
"avatar_url": "https://avatars.githubusercontent.com/u/6770?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/evanp",
"html_url": "https://github.com/evanp",
"followers_url": "https://api.github.com/users/evanp/followers",
"following_url": "https://api.github.com/users/evanp/following{/other_user}",
"gists_url": "https://api.github.com/users/evanp/gists{/gist_id}",
"starred_url": "https://api.github.com/users/evanp/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/evanp/subscriptions",
"organizations_url": "https://api.github.com/users/evanp/orgs",
"repos_url": "https://api.github.com/users/evanp/repos",
"events_url": "https://api.github.com/users/evanp/events{/privacy}",
"received_events_url": "https://api.github.com/users/evanp/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created_at": "2026-01-08T15:38:12Z",
"updated_at": "2026-01-08T15:38:12Z",
"body": "@keks had a good description of the problem in #57 .\n\n> Hi all! After talking to @mayel today, I skimmed the spec and I think I couldn't find any discussion of a challenge that many who want to use MLS in decentralized/distributed/federated settings face: the ordering of commits. The architecture document, though a bit high-level, has a [section][mlsarch-delivery] on it.\n\n> The core issue is that when you merge a commit, you should more or less immediately throw away the key material of the old epoch. The spec allows a little bit of leeway, but at the end of the day this is a problem for forward secrecy: leaving the old keys around means that when the device is compromised, messages from previous epochs can be decrypted.\n\n> Over in Matrix they had tried building \"[DMLS]\", which roughly does eventual consistency for MLS. Work on that angle seems to have stopped (imho that's good because \"i am going to delete the old encryption keys eventually\" is not a strong security statement). [Another proposal][MSC4256] suggests using the home server (similar to instance) of the group creator as an arbiter for the ordering of commits. \n\n> I just wanted to raise this issue because it's tricky to weigh the trade-offs and it would be a shame if it had to be addressed too late in the process.\n\n[DMLS]: https://gitlab.matrix.org/uhoreg/matrix-dmls\n[MSC4256]: https://github.com/matrix-org/matrix-spec-proposals/pull/4256\n[mlsarch-delivery]: https://www.rfc-editor.org/rfc/rfc9750.html#name-delivery-of-messages\n",
"author_association": "COLLABORATOR",
"pin": null,
"reactions": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3724435190/reactions",
"total_count": 1,
"+1": 1,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"performed_via_github_app": null
},
{
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3847943860",
"html_url": "https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3847943860",
"issue_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56",
"id": 3847943860,
"node_id": "IC_kwDOL_QsX87lWva0",
"user": {
"login": "uhoreg",
"id": 1012976,
"node_id": "MDQ6VXNlcjEwMTI5NzY=",
"avatar_url": "https://avatars.githubusercontent.com/u/1012976?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/uhoreg",
"html_url": "https://github.com/uhoreg",
"followers_url": "https://api.github.com/users/uhoreg/followers",
"following_url": "https://api.github.com/users/uhoreg/following{/other_user}",
"gists_url": "https://api.github.com/users/uhoreg/gists{/gist_id}",
"starred_url": "https://api.github.com/users/uhoreg/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/uhoreg/subscriptions",
"organizations_url": "https://api.github.com/users/uhoreg/orgs",
"repos_url": "https://api.github.com/users/uhoreg/repos",
"events_url": "https://api.github.com/users/uhoreg/events{/privacy}",
"received_events_url": "https://api.github.com/users/uhoreg/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created_at": "2026-02-04T14:56:16Z",
"updated_at": "2026-02-04T14:56:16Z",
"body": "FWIW, I just gave a talk at FOSDEM that explored some different attempts at using MLS in a decentralized/distributed environment: https://fosdem.org/2026/schedule/event/STAXFT-dmls_vs_dmls_decentralizingdistributing_messaging_layer_security/",
"author_association": "NONE",
"pin": null,
"reactions": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3847943860/reactions",
"total_count": 1,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 1
},
"performed_via_github_app": null
},
{
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3960528442",
"html_url": "https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3960528442",
"issue_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56",
"id": 3960528442,
"node_id": "IC_kwDOL_QsX87sEN46",
"user": {
"login": "evanp",
"id": 6770,
"node_id": "MDQ6VXNlcjY3NzA=",
"avatar_url": "https://avatars.githubusercontent.com/u/6770?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/evanp",
"html_url": "https://github.com/evanp",
"followers_url": "https://api.github.com/users/evanp/followers",
"following_url": "https://api.github.com/users/evanp/following{/other_user}",
"gists_url": "https://api.github.com/users/evanp/gists{/gist_id}",
"starred_url": "https://api.github.com/users/evanp/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/evanp/subscriptions",
"organizations_url": "https://api.github.com/users/evanp/orgs",
"repos_url": "https://api.github.com/users/evanp/repos",
"events_url": "https://api.github.com/users/evanp/events{/privacy}",
"received_events_url": "https://api.github.com/users/evanp/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created_at": "2026-02-25T16:37:25Z",
"updated_at": "2026-02-25T16:37:25Z",
"body": "Using a defined `context` with an `OrderedCollection` would help with this.\n\nChecking `published` order rather than received order is also good. I can check what the granularity on `published` is.\n\nKey renewal is up to the clients. Should happen when add/remove a client. Otherwise, we should check on the recommended time for this.",
"author_association": "COLLABORATOR",
"pin": null,
"reactions": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3960528442/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"performed_via_github_app": null
},
{
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3962083019",
"html_url": "https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-3962083019",
"issue_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56",
"id": 3962083019,
"node_id": "IC_kwDOL_QsX87sKJbL",
"user": {
"login": "uhoreg",
"id": 1012976,
"node_id": "MDQ6VXNlcjEwMTI5NzY=",
"avatar_url": "https://avatars.githubusercontent.com/u/1012976?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/uhoreg",
"html_url": "https://github.com/uhoreg",
"followers_url": "https://api.github.com/users/uhoreg/followers",
"following_url": "https://api.github.com/users/uhoreg/following{/other_user}",
"gists_url": "https://api.github.com/users/uhoreg/gists{/gist_id}",
"starred_url": "https://api.github.com/users/uhoreg/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/uhoreg/subscriptions",
"organizations_url": "https://api.github.com/users/uhoreg/orgs",
"repos_url": "https://api.github.com/users/uhoreg/repos",
"events_url": "https://api.github.com/users/uhoreg/events{/privacy}",
"received_events_url": "https://api.github.com/users/uhoreg/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created_at": "2026-02-25T21:07:23Z",
"updated_at": "2026-02-25T21:07:23Z",
"body": "It's not just about needing an ordering to the messages, but you also need to ensure that everyone receives the messages in the same order. (This includes ensuring that senders know, at the time of sending, that their message comes after someone else's message.) Because the purpose of the ordering in MLS is that Commit messages that are sent \"too late\" are discarded. But if someone has already applied the Commit, before they find out that it should have been disregarded, they'll be unable to participate in the group any further.\n\nFor example, if Alice and Bob both try to send a commit message based on the same epoch (say, Epoch 1). Alice's message is ordered first, but Carol receives Bob's message first. When Carol receives Bob's message, she applies Bob's commit, giving her an Epoch 2. At this point, she throws out the Epoch 1 `epoch_secret`, because MLS requires this for forward secrecy. She then receives Alice's message, which she find out should have been applied instead of Bob's, but since she already threw out the Epoch 1 `epoch_secret`, she can't create Alice's Epoch 2.",
"author_association": "NONE",
"pin": null,
"reactions": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/3962083019/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"performed_via_github_app": null
},
{
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/4396216497",
"html_url": "https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-4396216497",
"issue_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56",
"id": 4396216497,
"node_id": "IC_kwDOL_QsX88AAAABBgjwsQ",
"user": {
"login": "mayel",
"id": 115318,
"node_id": "MDQ6VXNlcjExNTMxOA==",
"avatar_url": "https://avatars.githubusercontent.com/u/115318?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/mayel",
"html_url": "https://github.com/mayel",
"followers_url": "https://api.github.com/users/mayel/followers",
"following_url": "https://api.github.com/users/mayel/following{/other_user}",
"gists_url": "https://api.github.com/users/mayel/gists{/gist_id}",
"starred_url": "https://api.github.com/users/mayel/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/mayel/subscriptions",
"organizations_url": "https://api.github.com/users/mayel/orgs",
"repos_url": "https://api.github.com/users/mayel/repos",
"events_url": "https://api.github.com/users/mayel/events{/privacy}",
"received_events_url": "https://api.github.com/users/mayel/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created_at": "2026-05-07T10:14:27Z",
"updated_at": "2026-05-07T10:22:59Z",
"body": "So after learning more about MLS, doing an initial implementation, and encountering some challenges with self-removals (see #80), here's an attempt at a proposal for a group actor approach which can serve as coordination hub for self-removal, decommission, and commit ordering.\n\n## Problem\n\nMLS requires that epoch secrets be discarded immediately after a Commit is applied. This means ordering errors are irrecoverable, as @uhoreg described above. This rules out eventual-consistency approaches. Every member must receive Commits in the **same order**, not just *an* order.\n\nIn a more P2P federated model, each member has an independent inbox with independent delivery latency, there is no shared total order. Timer-based staggering (as in our current implementation for self-removal from a group) reduces the collision probability but does not eliminate it, and adds latency proportional to group size.\n\n### Self-removal and decommission\n\nMLS imposes a further constraint: **a device cannot commit its own removal.** MLS's RFC 9420 only allows a member to issue a Remove *Proposal* for itself; another group member must produce and distribute the resulting Commit. In a federated group, coordinating which member commits, and ensuring all others receive that Commit in the correct order, is the same ordering problem, applied specifically to leave and decommission flows.\n\n## Prior discussions\n\nIn https://github.com/swicg/activitypub-e2ee/issues/80 @benpate frames the solution space as three approaches:\n\n1. **Designated committer**: only one device may commit epoch-incrementing proposals. Simple but impractical for real groups (e.g. that commiter client may be offline for a while).\n2. **Server-side epoch locking via a group relay actor**: a single actor orders and rejects duplicate-epoch Commits. Solves ordering and also fixes membership metadata leakage. Requires group-relay infrastructure. Also suggested in https://github.com/swicg/activitypub-e2ee/issues/78#issuecomment-4372911159\n3. **First-commit-wins + conflict detection**: timer/jitter-based staggering. No extra infrastructure, but fragile and adds latency proportional to group size.\n\n@evanp similarly suggested an `OrderedCollection` on the group initiator's server, and Matrix's MSC4256 proposes the group creator's server as ordering arbiter.\n\n## Proposed approach: group actor as AP-level sequencer\n\nThe Group actor pattern (described in https://github.com/swicg/activitypub-e2ee/issues/83, Options C and D1) is a realisation of the group relay idea using existing ActivityPub primitives ([FEP-1b12](https://codeberg.org/fediverse/fep/src/branch/main/fep/1b12/fep-1b12.md)).\n\nA Group actor on the origin server (i.e. the group creator's server) can act as a single inbox for all group MLS traffic. Because all members POST to the same inbox, the group actor's `Announce` stream provides a **total order** over all proposals and commits that every member observes identically, eliminating races without timers. `published` timestamps on activities provide a secondary ordering signal, but inbox-arrival order at a single actor is the authoritative sequence.\n\n### Self-removal and decommission\n\nThe leaving device sends its MLS Remove Proposal (as a `PrivateMessage`) to the group actor:\n\n```json\n{\n \"type\": \"Create\",\n \"actor\": \"https://server-b/users/bob\",\n \"to\": [\"https://server-a/group\"],\n \"object\": {\n \"type\": \"PrivateMessage\",\n \"mediaType\": \"message/mls\",\n \"encoding\": \"base64\",\n \"content\": \"<base64-encoded MLS Remove Proposal>\"\n }\n}\n```\n\nThe group actor Announces this to all members. Any coordination strategy can then be used to decide who commits (e.g. a co-device of the leaving member if one exists, a designated member by leaf index, or a timer-based fallback) but all of these are now **safe**: the group actor requires no MLS knowledge, it simply forwards all activities in inbox-arrival order. Clients apply the first valid Commit for their current epoch from the Announce stream and discard any subsequent one as `WrongEpoch`. All members observe the same ordered stream and land on the same winner.\n\nA decommissioning device similarly sends Remove Proposals to each group actor it belongs to. \n\n### Commit ordering \n\nThe race condition is not specific to removal \u2014 it applies to any operation where multiple members could produce a valid Commit for the same epoch simultaneously: adding a new member, key rotation (UpdatePath), or any batch of pending proposals. In a pure P2P model, resolving these races requires timer-based staggering for every Commit-producing operation.\n\nRouting all MLS group operations (Proposals, Commits, Welcomes) through the group actor solves this generally. Members send to the group actor via C2S; the group actor Announces to all followers in inbox-arrival order. All members see the same ordered stream of group state changes.\n\nRFC 9420 \u00a73.2 allows a committer to apply their Commit immediately only if they have assurance it will be the next one applied by the group. Receiving it back via the group actor's Announce stream is that assurance, it confirms the Commit is in the group actor's outbox and was the first to arrive for this epoch. Until that echo-back arrives, the client has no such assurance and must not apply.\n\nThe client workflow:\n1. Generate Commit, send to group actor, do **not** apply locally yet\n2. Watch the Announce stream:\n - Own Commit arrives first \u2192 confirmed winner, apply it, advance epoch\n - A competing Commit arrives first \u2192 discard pending Commit, apply the received one, re-propose if needed\n\nThe group actor forwards everything blindly in arrival order; clients use the ordered Announce stream to determine the winner. Together they eliminate the irrecoverable race without the group actor needing any MLS knowledge.\n\n\n## Two proposed changes\n\nThis proposal bundles two distinct changes:\n\n**1. Infrastructure: group actor as AP-level sequencer**\nA Group actor on the origin server provides a single inbox for all group MLS traffic and distributes an ordered Announce stream to all members. This is the delivery ordering mechanism, also described in https://github.com/swicg/activitypub-e2ee/issues/83 (options C and D1).\n\n**2. Client protocol change: apply Commits on receive, not on generation**\nCurrently, MLS-over-AP clients (including our implementation) apply a Commit immediately upon generating it. This proposal requires clients to instead hold the Commit in a pending state and apply it only when it arrives back via the authoritative channel (the group actor's Announce stream). This is the behavioral change that makes ordering guarantees meaningful, without it, the group actor's total order is irrelevant because clients have already diverged. \n\nIt also implies that potentially **any** ordered delivery channel (not only a group actor) could provide the same safety property, if clients adopt this behavior.\n\n## Tradeoffs\n\n| | Timer-based P2P (current) | Group actor hub |\n|---|---|---|\n| Commit ordering | Timer stagger, fragile | Total order via inbox |\n| Self-removal latency | `leafIndex \u00d7 2s` + co-device window | Near-instant (first committer wins deterministically) |\n| Single point of failure | None | Group actor's server |\n| Privacy | Each server sees full member list (can be mitigated by `bto`) | Hub sees server-level topology only (if using option D1) |\n| Infrastructure required | None | Group actor support (FEP-1b12) |\n\n## Relationship to #83\n\nThe same Group actor infrastructure that mitigates membership metadata exposure (Options C and D1 in #83) can also solve these MLS coordination problems. Implementing a group actor hub gives both privacy and ordering benefits with a single new infrastructure component.\n\n## Open questions\n\n- Is there interest in speccing the group actor as MLS coordination layer?\n- Should the group actor be a *required* component for federated MLS groups, or remain optional with P2P timer-based fallback?\n- Does the inbox-ordering guarantee hold across all AP server implementations, or do we need an explicit sequence number on activities?\n- If the group *creator* leaves the group, the sequencer itself can continue to function as long as the origin server accepts to keep the group running. \n- If the group actor's server goes offline, the group loses its sequencer entirely, and no new messages can be ordered or delivered. This is a critical reliability and sustainability concern. Supporting `Move` activity on groups can help, at least for planned server sun-setting.\n",
"author_association": "NONE",
"pin": null,
"reactions": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/4396216497/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"performed_via_github_app": null
},
{
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/4398091174",
"html_url": "https://github.com/swicg/activitypub-e2ee/issues/56#issuecomment-4398091174",
"issue_url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/56",
"id": 4398091174,
"node_id": "IC_kwDOL_QsX88AAAABBiWLpg",
"user": {
"login": "evanp",
"id": 6770,
"node_id": "MDQ6VXNlcjY3NzA=",
"avatar_url": "https://avatars.githubusercontent.com/u/6770?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/evanp",
"html_url": "https://github.com/evanp",
"followers_url": "https://api.github.com/users/evanp/followers",
"following_url": "https://api.github.com/users/evanp/following{/other_user}",
"gists_url": "https://api.github.com/users/evanp/gists{/gist_id}",
"starred_url": "https://api.github.com/users/evanp/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/evanp/subscriptions",
"organizations_url": "https://api.github.com/users/evanp/orgs",
"repos_url": "https://api.github.com/users/evanp/repos",
"events_url": "https://api.github.com/users/evanp/events{/privacy}",
"received_events_url": "https://api.github.com/users/evanp/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created_at": "2026-05-07T14:39:36Z",
"updated_at": "2026-05-07T14:39:36Z",
"body": "We have two solutions to do:\n\n1. Conversation/context thread managed by the group initiator. Depends on a pull mechanism by the clients to confirm ordering.\n2. Group actor that announces the content, adding some activity ordering.\n\n",
"author_association": "COLLABORATOR",
"pin": null,
"reactions": {
"url": "https://api.github.com/repos/swicg/activitypub-e2ee/issues/comments/4398091174/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"performed_via_github_app": null
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment