



  

<!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">

<script type="importmap">{"imports":{"react":"https://github.githubassets.com/assets/react-e27d1b3e03961e68.js","react-dom":"https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js","react-dom/client":"https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js","react-is":"https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js","react-reconciler":"https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js","react/compiler-runtime":"https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js","react/jsx-dev-runtime":"https://github.githubassets.com/assets/react-jsx-dev-runtime-ea55d68667d559e5.js","react/jsx-runtime":"https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js","scheduler":"https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js"}}</script>
<meta name="react-profiling" content="0" data-turbo-transient="true" />
<meta name="react-import-map" content="react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@777f63f87cd0" data-turbo-track="reload" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-e27d1b3e03961e68.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js" />

  


  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-0f910d8806d5761b.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-a7abd4d4c49ac593.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-5fc4c4a9cb41e596.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-ed0cee9214dedabd.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-78a2491d538dab5a.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-c26b63d7c532d0a2.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-a6f60cea68c08405.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-f66faf28b2ea18b6.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-6701f6218c53cf5b.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-7037fa46ae124d97.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-97df7784617ce1ea.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-9be9fe6313f476af.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-62747e27e61258dc.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-b04ca6fccda778e2.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-72bd7d974b5ac1cc.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-4c5c0895f723f870.css" />

  

  <script type="application/json" id="client-env">{"locale":"en","featureFlags":["actions_caches_react_shell","actions_enable_background_steps","actions_new_hosted_runner_image_select_sizes_and_versions","actions_runners_react_shell","agent_author_search_expansion","agent_author_search_expansion_ui_pulls","alternate_user_config_repo","async_conversion_coverage_enabled","billing_billable_licenses_cost_center_bucket_fix","billing_budget_expiration","billing_cost_center_list_assigned_resources","billing_discount_threshold_notification","code_quality_enablement_banner_targeting","code_quality_remove_preview","code_view_raf_sticky_lines","codespaces_prebuild_region_target_update","coding_agent_third_party_model_ui","copilot_agent_snippy","copilot_ahp_tool_call_timing","copilot_api_agentic_issue_marshal_yaml","copilot_automation_repo_mcp_servers","copilot_automations_pagination","copilot_base_model_policy_row","copilot_chat_auto_mode_v2","copilot_chat_clear_model_selection_for_default_change","copilot_chat_early_task_provisioning","copilot_chat_persist_session_drafts","copilot_chat_vision_dotcom_chat_ga_gate","copilot_css_textarea_autosize","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_removal_on_marketplace","copilot_fix_failed_workflows_all_skus","copilot_hide_hovercard","copilot_immersive_task_hyperlinking","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_merge_fix_ci","copilot_mission_control_agent_merge_resolve_conflicts","copilot_mission_control_awps_batching","copilot_mission_control_early_stop","copilot_mission_control_managed_sandbox_environments","copilot_mission_control_needs_attention","copilot_mission_control_reasoning_effort","copilot_mission_control_sandbox_remote_bypass","copilot_mission_control_task_alive_updates","copilot_mission_control_task_sharing","copilot_org_policy_page_focus_mode","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_swe_agent_authorization_status_ui","copilot_swe_agent_automation_resource_scoped_writes","copilot_swe_agent_discussion_comment_trigger","copilot_swe_agent_discussion_opened_trigger","copilot_swe_agent_discussion_updated_trigger","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_issue_assigned_trigger","copilot_swe_agent_issue_comment_trigger","copilot_swe_agent_issue_labeled_trigger","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_pull_request_assigned_trigger","copilot_swe_agent_pull_request_comment_trigger","copilot_swe_agent_pull_request_labeled_trigger","copilot_swe_agent_pull_request_merged_trigger","copilot_swe_agent_pull_request_opened_trigger","copilot_swe_agent_pull_request_ready_for_review_trigger","copilot_swe_agent_pull_request_review_requested_trigger","copilot_swe_agent_pull_request_review_submitted_trigger","copilot_swe_agent_pull_request_synchronize_trigger","copilot_swe_agent_sub_issue_added_trigger","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_task_scoped_alive_channel","copilot_token_based_billing","copilot_unconfigured_is_inherited","copilot_user_can_upgrade_plan_field","copilot_web_integration_cutover","copilot_workbench_sunset_redirect","dashboard_agents_module_auth_token_check","dashboard_indexeddb_caching","fgpat_permissions_selector_redesign","glc_code_quality_repo_settings_workflow_config","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","in_product_messaging_datadog_monitoring","ipm_ubb_individual_budget_banner","issue_fields_multi_select","issue_inline_avatars","issue_pinned_views","issue_pinned_views_team_vs_personal","issue_relative_time_micro","issue_viewer_paved_path","issues_expanded_file_types","issues_hide_closed_sub_issues","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","labels_archiving","labels_archiving_info","landing_pages_ninetailed","lifecycle_label_name_updates","marketing_cookie_consent_banner","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_queue_restricted_pushers_warning","merge_status_header_feedback","milestone_closed_issues_prioritization","octocaptcha_origin_optimization","primer_react_css_anchor_positioning","primer_react_merged_forwarded_refs","primer_react_timeline_list_semantics","prs_copilot_app_open_action","prs_css_anchor_positioning","pull_request_copilot_attribution_header","pull_request_overview_merge_control","pull_request_overview_panel_edit_description","pull_request_persister","pull_request_stacks_navigation_shortcuts","pull_request_virtualization_image_estimate","pull_request_virtualization_loader_batching","pull_request_virtualization_scroll_compensation","pull_request_virtualization_scroll_intent","quick_search_lazy_suggestions","react_blob_isolate_code_lines","react_blob_ssr_content_visibility","react_data_router_tanstack_allowed","react_logged_out_repository_header","react_query_props_with_key","react_sandbox_future_tanstack","repo_app_turbo","repo_issues_sidebar_layout","repo_pulls_dashboard_declutter","repo_pulls_dashboard_ga","repo_pulls_dashboard_persistence","repos_contributors_limited_default_range","review_involves_filter","rule_ignored_file_paths","rulesets_actor_list_editor","sample_network_conn_type","security_center_artifact_filters_popover","see_who_reacted","semantic_similarity_duplicate_issue_detection","session_logs_ungroup_reasoning_text","set_sha256_on_repo_creation_form","site_banner_desktop_copilot_app","site_ghca_pixel_mona","site_github_app_ga_page","site_github_app_ga_page_highlight","site_github_app_mobile_native_share","site_global_banner_dev_days_attendee","site_global_nav_spark_models_removed","speculation_rules_ui_service","suggest_custom_property_values_copilot","suppress_automated_browser_vitals","swp_forms_disable_octocaptcha","thread_resolution_reason","update_issue_suggestions","viewscreen_sandbox","warn_inaccessible_attachments","webp_support","workstream_plugin_bootstrap"],"githubDomain":"https://github.com","copilotApiOverrideUrl":"https://api.githubcopilot.com","cmcApiUrl":"https://api.github.com/cmc_internal/api"}</script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/high-contrast-cookie-3663bcaacc724f4c.js"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-runtime-e7610307df12a842.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-foundation-156c6259e31cc551.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-runtime-f6ce38f47c2e1d56.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fetch-utilities-804a14996977c014.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ser-fb5d13278eb42203.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tp-ea613009a991e211.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/environment-24e561c65e946f7d.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-runtime.25915bc98fb322a6.module.css" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/catalyst-52ed81112a548e10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/selector-observer-e8810f64c443fb9b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/relative-time-element-fe7e72f699fdf493.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/by-9da36843ba9d191d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ja9-9a1160b939f2cd52.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3h-55903cf2303047ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hk-0d35a1220587d888.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jz5-c964b1a3671f2a92.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hj-1d800d09e9a8720a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j0-1ad12374da9777f2.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/github-elements-b0e284afdb522622.js" defer="defer"></script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/element-registry-10109ffb41067b06.js" defer="defer"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/runtime-helpers-5e0b3ae3c4036207.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/aria-live-752acdc868e2da64.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hotkey-e87ffadced20a3c9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-core-75bc55d9971828b7.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a9-34620c7b13885011.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ur-643d2814115561a9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4t6-5d0869970ac0aac0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/pb0-a5c5ec36d311aeef.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6n-afcf86ccabc4cad2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zj-f08c728cf00018aa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/o6-2a1c68d269710ee9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/h9a-c6405aa090de0e84.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/vy6-3c3e6e96629c2ce4.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/js-4eb97d5803e657c0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/g7-baf9e817ae102b01.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/unc-96389cade7bad821.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/nu-65322a6997c6c93c.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/behaviors-54f7deb7d2612e69.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-core.3792087592bf207a.module.css" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-menu-f0ae3472e0ece411.js" defer="defer"></script>
  
  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/primer-react-7afef75d393cf294.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/op-acddf38478d45ef9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ncx-461e4b09f2e67ee5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qmp-c7cfba40cf5a93b0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j6-148a74299e5a01ab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t7l-a52ba56147f77909.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4u-ec4874f70bfd5d76.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/s0-481bd34f90bc2bd7.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y5-ed17e73b4c0bd15e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/n4-be595475cdbf7d4b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j8-23a3c5ff8eef412d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/la-27679061f16e1495.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/iu-9806a0291a782cbe.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ftx-39fb490e3c1d778f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zi-32a0c3c081ea5cce.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sg-7a5d50475874c0e1.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/pd-6a8710840033e042.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/86g-ec28c25ed7d5de06.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sn-1bab7384818953b7.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/iq-6d4ecf6d2fb6993c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/p2-7d8e7cee5b46cb45.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7d-2e3cc25d719f3a95.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4d-76d8acdf21a33266.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tsb-e0f6288ab985d9d2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/lf-910ef220ce85c660.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2j-2f19c1afd2ceaf93.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/me-f1476ec44a29f34a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/p2u-e654a57b1a70c47d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/5d-d97cc006d4da4d9b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/r5-38f013bc2c0fd298.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/r6s-9039f5619230a653.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/9e-cece06724bf6ea3b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/x9-3e077a3a37a73f9f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/pj-87629cb5389d7663.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/eq-3764fd5f66494289.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/13-d889936dff7e5c0f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/44-8193eea4af825ead.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/v4-9c1327d212e52a0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/id-7f39706ba9007db6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ah-271362a1ed227d03.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/s1g-d434d712bca59d3a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/vz-d7f4a583896f872e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/47-c8c0ce2700acc5be.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-view-49c8cee7840c9c82.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.2d881b4d4a503d1c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/pj.75627bfeb9ceb1da.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ah.2623f7c6ecbe2ecd.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/47.78770c57a48a810c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-view.35603ecb2160763e.module.css" />


  <title>patchrail/CHANGELOG.md at v0.5.0 · patchrail/patchrail · GitHub</title>



  <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient>
  <meta name="route-controller" content="blob" data-turbo-transient>
  <meta name="route-action" content="show" data-turbo-transient>
  <meta name="fetch-nonce" content="v2:3af039b2-d48e-4d20-3771-faaa01daf001">

    
  <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb">


  <meta name="request-id" content="99D8:3184D2:11E2B0:1608A7:6ACB8ACF" data-pjax-transient="true"/><meta name="html-safe-nonce" content="07fa317494f6f99aecf55c295336c1ad2e8185cc901ddaaccde753884292fd72" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5OUQ4OjMxODREMjoxMUUyQjA6MTYwOEE3OjZBQ0I4QUNGIiwidmlzaXRvcl9pZCI6IjMwMTc5MTYyMTMyMTg3NDA5NDMiLCJyZWdpb25fZWRnZSI6ImZyYSIsInJlZ2lvbl9yZW5kZXIiOiJmcmEifQ==" data-pjax-transient="true"/><meta name="visitor-hmac" content="194b5d631cf48385d5de7fbb01f8d45e345290534f7f2fcb68eecd6ef8f0ac80" data-pjax-transient="true"/>


    <meta name="hovercard-subject-tag" content="repository:1257620736" data-turbo-transient>


  <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" />
  

  <meta name="selected-link" value="repo_source" 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;/blob/show" data-turbo-transient="true" />

  




    <meta name="user-login" content="">

  

    <meta name="viewport" content="width=device-width">

    

      <meta name="description" content="Local-first maintainer automation: explain CI failures, queue agent work, and ship safer OSS releases. - patchrail/CHANGELOG.md at v0.5.0 · patchrail/patchrail">

      <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/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md" />

      <meta name="twitter:image" content="https://opengraph.githubassets.com/9ef8f4d6e224b7c3a010e724b614292517aa28abf2049ffbe7c84e43887ed392/patchrail/patchrail" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="patchrail/CHANGELOG.md at v0.5.0 · patchrail/patchrail" /><meta name="twitter:description" content="Local-first maintainer automation: explain CI failures, queue agent work, and ship safer OSS releases. - patchrail/patchrail" />
  <meta property="og:image" content="https://opengraph.githubassets.com/9ef8f4d6e224b7c3a010e724b614292517aa28abf2049ffbe7c84e43887ed392/patchrail/patchrail" /><meta property="og:image:alt" content="Local-first maintainer automation: explain CI failures, queue agent work, and ship safer OSS releases. - patchrail/patchrail" /><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="patchrail/CHANGELOG.md at v0.5.0 · patchrail/patchrail" /><meta property="og:url" content="https://github.com/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md" /><meta property="og:description" content="Local-first maintainer automation: explain CI failures, queue agent work, and ship safer OSS releases. - patchrail/patchrail" />
  




      <meta name="hostname" content="github.com">



        <meta name="expected-hostname" content="github.com">


  <meta http-equiv="x-pjax-version" content="e340c92f5eb45f6fb6db73d43b8fee8cb69889b4676afb76c5381963d7bd24ed" data-turbo-track="reload">
  <meta http-equiv="x-pjax-csp-version" content="c4a65e47b0c850e1157ae8e66298070851d7e3b558038de5a3b4ff7a93e630ed" data-turbo-track="reload">
  <meta http-equiv="x-pjax-css-version" content="a80b0545b169f440b929ce2b977c76b6988f014cca6513fb83c5df6581635fb3" data-turbo-track="reload">
  <meta http-equiv="x-pjax-js-version" content="86c024975ec65bef61977fbe60782866bd2f48cf8401c77b0337e58b2cab7952" data-turbo-track="reload">

  <meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">

      <meta name="turbo-cache-control" content="no-cache" data-turbo-transient>

    <meta data-hydrostats="publish">

  <meta name="go-import" content="github.com/patchrail/patchrail git https://github.com/patchrail/patchrail.git">

  <meta name="octolytics-dimension-user_id" content="284771939" /><meta name="octolytics-dimension-user_login" content="patchrail" /><meta name="octolytics-dimension-repository_id" content="1257620736" /><meta name="octolytics-dimension-repository_nwo" content="patchrail/patchrail" /><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="1257620736" /><meta name="octolytics-dimension-repository_network_root_nwo" content="patchrail/patchrail" />
  



    

    <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="f3c33252c136837d4801bc973e01d185db642a57" data-turbo-track="reload">
  <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" rel="modulepreload" href="https://github.githubassets.com/assets/19-c660652a0a1639be.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-5af6e2671bf3c355.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.2d881b4d4a503d1c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.9a3346a06fe1e0b7.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>





      

          <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-install-banner-partial-7cdb285eb17304a3.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.2d881b4d4a503d1c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-install-banner-partial.23da07a41d5b850d.module.css" />

<react-partial
  partial-name="app-install-banner-partial"
  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>


          

                <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/et9-7eeec247c287fca4.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/94v-e20946127faa8f6e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fz5-892a9e99cc92858d.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jag-441e702bfd4c7904.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hw-8ce7888b57d0a23c.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/rq-0ec82a12cf538a4d.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/1m-a7a4c022483b2713.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/marketing-header-d6527f1bfaca19f3.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.2d881b4d4a503d1c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-brand-css.fbc35b3d20e988ff.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/1m.fec8b575d0e5234f.module.css" />

<react-partial
  partial-name="marketing-header"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"color_mode":"dark","logged_in":false,"marketing_page":false,"home_path":"/","login_path":"/login?return_to=https%3A%2F%2Fgithub.com%2Fpatchrail%2Fpatchrail%2Fblob%2Fv0.5.0%2FCHANGELOG.md","signup_path":"/signup?ref_cta=Sign+up\u0026ref_loc=header+logged+out\u0026ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow\u0026source=header-repo\u0026source_repo=patchrail%2Fpatchrail","signup_enabled":true,"is_signup_controller":false,"show_search_and_nav":true,"hide_search":false,"private_mode_enabled":false,"should_use_dotcom_links":true,"auth_hydro_click":"{\"event_type\":\"authentication.click\",\"payload\":{\"location_in_page\":\"site header menu\",\"repository_id\":null,\"auth_type\":\"SIGN_UP\",\"originating_url\":\"https://github.com/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md\",\"user_id\":null}}","auth_hydro_click_hmac":"2066729da14c34a9691f3f951ef903bceca4c0840621bb66f86a1f020eda78bf","overlay":false,"fixed":false}}</script>
  <div data-target="react-partial.reactRoot"><div data-color-mode="dark" data-light-theme="light" data-dark-theme="dark"><header class="MarketingHeader-module__root__Tk7n3 HeaderMktg header-logged-out" role="banner" data-marketing-header="true" data-color-mode="dark" data-light-theme="light" data-dark-theme="dark" data-is-top="true"><h2 class="MarketingHeader-module__visuallyHidden__sqKsl">Navigation Menu</h2><button type="button" class="MarketingHeader-module__backdrop__sw4RU" aria-label="Close navigation menu"></button><div class="MarketingHeader-module__bar__mBSyE"><div class="MarketingHeader-module__topRow__yeury"><div class="MarketingHeader-module__toggleSlot__hDxbh"><button type="button" class="HeaderMenuToggle-module__toggle__i8EiC" aria-label="Toggle navigation" aria-expanded="false"><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span></button></div><a href="/" aria-label="Homepage" class="HeaderLogo-module__logo__UFyHI" data-analytics-event="{&quot;action&quot;:&quot;homepage&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;logo&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;homepage_link_logo_header&quot;}"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github" viewBox="0 0 24 24" width="32" height="32" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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="AuthCTAs-module__mobileActions__NNzeV"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fpatchrail%2Fpatchrail%2Fblob%2Fv0.5.0%2FCHANGELOG.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" 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/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="2066729da14c34a9691f3f951ef903bceca4c0840621bb66f86a1f020eda78bf"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_3dd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_3dd_">Appearance settings</div></div></div><div class="MarketingHeader-module__menu__GIy3y"><div class="MarketingHeader-module__menuWrapper__owstH"><nav class="MarketingNavigation-module__nav__W0KYY" aria-label="Global"><ul class="MarketingNavigation-module__list__tFbMb"><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_nd_">Platform<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-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.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5knd_">AI CODE CREATION</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>GitHub Copilot</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Write better code with AI</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/ai/github-app" data-analytics-event="{&quot;action&quot;:&quot;github_copilot_app&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_app_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"></path></svg>GitHub Copilot app</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Direct agents from issue to merge</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.52 1.12a3.578 3.578 0 0 1 6.078 2.98 3.578 3.578 0 0 1 2.982 6.08l-3.292 3.293a.252.252 0 0 0 0 .354l.843.843a.749.749 0 1 1-1.06 1.06l-.844-.843a1.75 1.75 0 0 1 0-2.474L13.52 9.12a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0L7.731 9.03A.75.75 0 0 1 6.67 7.97l2.85-2.85a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0l-4.799 4.8A.75.75 0 0 1 .72 5.92Z"></path><path d="M7.52 3.12a.749.749 0 1 1 1.06 1.06L5.731 7.03A2.079 2.079 0 0 0 8.67 9.97l2.85-2.85a.749.749 0 1 1 1.06 1.06l-2.849 2.85A3.578 3.578 0 0 1 4.67 5.97Z"></path></svg>MCP Registry</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Integrate external tools</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9knd_">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>Actions</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Automate any workflow</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>Codespaces</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Instant dev environments</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon__ltGNM" 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>Issues</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Plan and track work</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>Code Review</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Manage code changes</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-quality" data-analytics-event="{&quot;action&quot;:&quot;code_quality&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_quality_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codescan-checkmark NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.28 6.28a.75.75 0 1 0-1.06-1.06L6.25 8.19l-.97-.97a.75.75 0 0 0-1.06 1.06l1.5 1.5a.75.75 0 0 0 1.06 0l3.5-3.5Z"></path><path d="M7.5 15a7.5 7.5 0 1 1 5.807-2.754l2.473 2.474a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2.474-2.473A7.472 7.472 0 0 1 7.5 15Zm0-13.5a6 6 0 1 0 4.094 10.386.748.748 0 0 1 .293-.292 6.002 6.002 0 0 0 1.117-6.486A6.002 6.002 0 0 0 7.5 1.5Z"></path></svg>Code Quality</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enforce quality at merge</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dknd_">APPLICATION SECURITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Find and fix vulnerabilities</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>Code security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Secure your code as you build</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>Secret protection</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Stop leaks before they start</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ NavGroup-module__hasSeparator__FnMrN"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_hknd_">EXPLORE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_hknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Why GitHub</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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 class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Blog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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 class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Changelog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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 class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all features</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_17d_">Solutions<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-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.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_17d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5l7d_">BY COMPANY SIZE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Enterprises</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Small and medium teams</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Startups</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9l7d_">BY USE CASE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">App Modernization</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevSecOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">CI/CD</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all use cases</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dl7d_">BY INDUSTRY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dl7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Healthcare</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Financial services</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Manufacturing</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Government</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all industries</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all solutions</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_1nd_">Resources<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-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.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_1nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5lnd_">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">AI</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Software Development</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all topics</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9lnd_">EXPLORE BY TYPE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer stories</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Events &amp; webinars</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Ebooks &amp; reports</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Business insights</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Skills</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dlnd_">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dlnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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 class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer support</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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 class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Community forum</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trust center</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Partners</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all resources</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_27d_">Open Source<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-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.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_27d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5m7d_">COMMUNITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/open-source/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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.586 1C12.268 1 13.5 2.37 13.5 4.25c0 1.745-.996 3.359-2.622 4.831-.166.15-.336.297-.509.438l1.116 5.584a.75.75 0 0 1-.991.852l-2.409-.876a.25.25 0 0 0-.17 0l-2.409.876a.75.75 0 0 1-.991-.852L5.63 9.519a13.78 13.78 0 0 1-.51-.438C3.497 7.609 2.5 5.995 2.5 4.25 2.5 2.37 3.732 1 5.414 1c.963 0 1.843.403 2.474 1.073L8 2.198l.112-.125a3.385 3.385 0 0 1 2.283-1.068L10.586 1Zm-3.621 9.495-.718 3.594 1.155-.42a1.75 1.75 0 0 1 1.028-.051l.168.051 1.154.42-.718-3.592c-.199.13-.37.235-.505.314l-.169.097a.75.75 0 0 1-.72 0 9.54 9.54 0 0 1-.515-.308l-.16-.105ZM10.586 2.5c-.863 0-1.611.58-1.866 1.459-.209.721-1.231.721-1.44 0C7.025 3.08 6.277 2.5 5.414 2.5 4.598 2.5 4 3.165 4 4.25c0 1.23.786 2.504 2.128 3.719.49.443 1.018.846 1.546 1.198l.325.21.076-.047.251-.163a13.341 13.341 0 0 0 1.546-1.198C11.214 6.754 12 5.479 12 4.25c0-1.085-.598-1.75-1.414-1.75Z"></path></svg>GitHub Sponsors</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Fund open source developers</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9m7d_">PROGRAMS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security Lab</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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 class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Maintainer Community</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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 class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Stars</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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 class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" 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;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Archive Program</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" 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="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="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dm7d_">REPOSITORIES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dm7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Topics</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trending</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_2nd_">Enterprise<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-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.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_2nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5mnd_">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.122.392a1.75 1.75 0 0 1 1.756 0l5.003 2.902c.83.481.83 1.68 0 2.162L8.878 8.358a1.75 1.75 0 0 1-1.756 0L2.119 5.456a1.251 1.251 0 0 1 0-2.162ZM8.125 1.69a.248.248 0 0 0-.25 0l-4.63 2.685 4.63 2.685a.248.248 0 0 0 .25 0l4.63-2.685ZM1.601 7.789a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0L1.874 8.814A.75.75 0 0 1 1.6 7.789Zm0 3.5a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0l-5.248-3.044a.75.75 0 0 1-.273-1.025Z"></path></svg>Enterprise platform</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">AI-powered developer platform</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9mnd_">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade security features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" 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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>Copilot for Business</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade AI features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise/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;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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>Premium Support</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade 24/7 support</span></span></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="MarketingNavigation-module__navLink__hUomM">Pricing</a></li></ul></nav><div class="MarketingHeader-module__ctaContainer__tBmPz"><div class="HeaderSearch-module__searchSlot__oVOUS"><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderSearch-module__trigger__zsF9q" type="button" aria-haspopup="dialog" aria-expanded="false" aria-label="Search or jump to, type / to search" data-analytics-event="{&quot;action&quot;:&quot;searchbar&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;context&quot;:&quot;global&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"><span class="HeaderSearch-module__content__kMpxU"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search HeaderSearch-module__icon__wcrHX" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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 class="HeaderSearch-module__label__d1iWG">Search</span><kbd class="HeaderSearch-module__kbd__HNG0o" aria-hidden="true">/</kbd></span></span></span></button><div class="d-none"></div></div><div class="AuthCTAs-module__signInWrap__q2P60"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq AuthCTAs-module__desktopActionGap__UZuXT AuthCTAs-module__hiddenBelowLg__BfKBw" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fpatchrail%2Fpatchrail%2Fblob%2Fv0.5.0%2FCHANGELOG.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" 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/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="2066729da14c34a9691f3f951ef903bceca4c0840621bb66f86a1f020eda78bf"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a></div><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--secondary___gHnw_ Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=patchrail%2Fpatchrail" data-analytics-event="{&quot;action&quot;:&quot;sign_up&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_up_link_auth_cta_header&quot;}" 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/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="2066729da14c34a9691f3f951ef903bceca4c0840621bb66f86a1f020eda78bf"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-secondary___eJ0_a">Sign up</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_fbd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_fbd_">Appearance settings</div></div></div></div></div><div class="MarketingHeader-module__bottomBorder__uZT38" aria-hidden="true"></div></header></div></div>
</react-partial>



      <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-ea85d2c3-06b8-4fad-a392-9d771fd12377" aria-labelledby="tooltip-a68dadc1-e4e0-4530-a9b3-f04146354624" 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-a68dadc1-e4e0-4530-a9b3-f04146354624" for="icon-button-ea85d2c3-06b8-4fad-a392-9d771fd12377" 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" >
      
      
    


    








  

    <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ym-6bc2c9bf8112c038.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sk2-8deeef9351be3911.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ni-3e194d222c7770bf.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7x-71d30cb240cd901f.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wwk-ad869086822937b1.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a1-9f79841ecac1da8e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wzg-40a3213b3e83400b.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/5f-64f8e7d5bcbd4787.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/z5-b53a93078d026f1e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/8h-cef26f68c1331011.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fq-3ce13a77e863807a.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a7-596b507bd20acddc.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xfx-c82d8352413aea0a.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j4-b3a9e87fa7878a98.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/global-nav-bar-b658a668f60ca56f.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.2d881b4d4a503d1c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/pj.75627bfeb9ceb1da.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-nav-bar.d9f1a8b5518e8da4.module.css" />

<react-partial
  partial-name="global-nav-bar"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"contextRegion":{"crumbs":[{"crumb_type":"organization","label":"patchrail","is_root":false,"href":"/patchrail"},{"crumb_type":"repository","label":"patchrail","is_root":false,"href":"/patchrail/patchrail"}],"localNavigation":[{"id":"code","icon":"code","label":"Code","href":"/patchrail/patchrail","selectedLinks":["repo_source","repo_downloads","repo_commits","repo_releases","repo_tags","repo_branches","repo_packages","repo_deployments","repo_attestations"],"popoverTarget":false,"commandId":"repositories:go-to-code","reactNav":{"appTarget":"code-view","anchor":"code-view-repo-link"},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"issues","icon":"issue-opened","label":"Issues","href":"/patchrail/patchrail/issues","selectedLinks":["repo_issues","repo_labels","repo_milestones"],"count":21,"popoverTarget":false,"commandId":"repositories:go-to-issues","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"pull-requests","icon":"git-pull-request","label":"Pull requests","href":"/patchrail/patchrail/pulls","selectedLinks":["repo_pulls","checks"],"count":1,"popoverTarget":false,"commandId":"repositories:go-to-pull-requests","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"actions","icon":"play","label":"Actions","href":"/patchrail/patchrail/actions","selectedLinks":["repo_actions"],"popoverTarget":false,"commandId":"repositories:go-to-actions","reactNav":{"appTarget":"actions-workflows","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"projects","icon":"table","label":"Projects","href":"/patchrail/patchrail/projects","selectedLinks":["repo_projects","new_repo_project","repo_project"],"popoverTarget":false,"commandId":"repositories:go-to-projects","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"security-and-quality","icon":"shield","label":"Security and quality","href":"/patchrail/patchrail/security","selectedLinks":["security","overview","alerts","policy","token_scanning","code_scanning"],"count":0,"popoverTarget":false,"commandId":"repositories:go-to-security","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"insights","icon":"graph","label":"Insights","href":"/patchrail/patchrail/pulse","selectedLinks":["repo_graphs","repo_contributors","dependency_graph","dependabot_updates","pulse","people","community"],"popoverTarget":false,"commandId":"repositories:go-to-insights","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}}],"localNavigationUpdateChannel":null,"selectedLink":"repo_source"},"owner":null,"headerLogo":{"href":"/","aria-label":"Homepage "},"notifications":{"indicatorMode":"disabled","websocketChannel":null,"fetchIndicatorSrc":"/notifications/indicator","fetchIndicatorEnabled":false},"issues":{"href":"/issues"},"pulls":{"href":"/pulls"},"contributedRepos":{"href":"/repos"},"copilot":{"show":false,"showAgentsButton":false,"showRelaunchAnnouncement":false,"copilotChatUrl":null,"copilotApiUrl":"https://api.githubcopilot.com"},"search":{"show":true,"showCommandPalette":false,"isSearchPage":false,"isJumpToSearch":false,"searchContext":{"scope":"repo:patchrail/patchrail","current_repo_name":"patchrail","current_repo_nwo":"patchrail/patchrail","current_repo_org":"patchrail","user_id":"patchrail"}},"commandPalette":null,"enterpriseBar":{"show":false},"globalTransactionalMessage":[],"payloadsUrl":"/_global-navigation/payloads.json?can_toggle_site_admin_and_employee_status=0\u0026is_admin_mode_on=0\u0026is_ui_opted_out=0\u0026show_ui_opt_out=0\u0026v=7","contextRegionUrl":"/_global-navigation/context-region.json"}}</script>
  <div data-target="react-partial.reactRoot"><header aria-label="Global navigation menu" data-component="Stack" class="GlobalNav styles-module__appHeader__YzYWk prc-Stack-Stack-UQ9k6" data-gap="none" data-direction="vertical" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="none"><div data-component="Stack" class="prc-Stack-Stack-UQ9k6" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="center" data-padding="none"><div data-testid="top-nav-center" data-component="Stack" class="styles-module__center__R3QRv styles-module__withLocalNavigation__rjTJ_ GlobalNavBar-module__loggedOut__Jv1rk prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="normal"><nav class="styles-module__contextRegion__VbSp2 prc-Breadcrumbs-BreadcrumbsBase-3Gb-B" aria-label="Breadcrumbs" data-overflow="menu" data-variant="normal" data-component="Breadcrumbs"><ol class="prc-Breadcrumbs-BreadcrumbsList-BKjpe"><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/patchrail" data-discover="true"><span class="">patchrail</span></a></li><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/patchrail/patchrail" data-discover="true"><span class="styles-module__contextCrumbLast__tI2e3">patchrail</span></a></li></ol></nav></div><div data-testid="top-nav-right" data-component="Stack" class="styles-module__right__mlBQg styles-module__withLocalNavigation__rjTJ_ styles-module__rightWithResponsiveCreateButton__SKn2W prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="start" data-padding="normal"></div></div><h2 class="prc-src-InternalVisuallyHidden-2YaI6">Repository navigation</h2><nav class="prc-components-UnderlineWrapper-eT-Yj prc-UnderlineNav-UnderlineWrapper-GWONT LocalNavigation-module__LocalNavigation__b0Xc0" aria-label="Repository" data-variant="inset" data-overflow-mode="wrap" data-hide-icons-breakpoint="medium"><ul class="prc-UnderlineNav-ItemsList-oj8gN prc-components-UnderlineItemList-xKlKC" role="list"><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a aria-current="page" data-tab-item="code" data-react-nav="code-view" data-react-nav-anchor="code-view-repo-link" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/patchrail/patchrail" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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-component="text" data-content="Code">Code</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="issues" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/patchrail/patchrail/issues" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened" 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></span><span data-component="text" data-content="Issues">Issues</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">21</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->21<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="pull-requests" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/patchrail/patchrail/pulls" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-pull-request" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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-component="text" data-content="Pull requests">Pull requests</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">1</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->1<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="actions" data-react-nav="actions-workflows" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/patchrail/patchrail/actions" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-play" 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 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-component="text" data-content="Actions">Actions</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="projects" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/patchrail/patchrail/projects" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-table" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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-component="text" data-content="Projects">Projects</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="security-and-quality" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/patchrail/patchrail/security" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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-component="text" data-content="Security and quality">Security and quality</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="insights" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/patchrail/patchrail/pulse" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-graph" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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-component="text" data-content="Insights">Insights</span></a></li></ul><div class="prc-UnderlineNav-MoreButtonContainer-Dnrq6"><div class="prc-UnderlineNav-MoreButtonDivider-dN0a-"></div><button data-component="overflow-menu-button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk prc-UnderlineNav-MoreButton-Y8soj" data-loading="false" data-size="medium" data-variant="invisible" id="_R_2ktp_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3"><span>More<span class="prc-src-InternalVisuallyHidden-2YaI6"> items</span></span></span></span><span data-component="trailingAction" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></button></div></nav><div class="d-none"></div></header></div>
</react-partial>


  



<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class="">
    <div id="repo-content-pjax-container" class="repository-content " >
    



    
      
    








<react-app
  app-name="code-view"
  initial-path="/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md"
  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="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-app.embeddedData">{"payload":{"codeViewBlobRoute":{"csv":null,"csvError":null,"headerInfo":{"toc":[{"level":1,"text":"Changelog","anchor":"changelog","htmlText":"Changelog"},{"level":2,"text":"0.5.0 - 2026-07-14","anchor":"050---2026-07-14","htmlText":"0.5.0 - 2026-07-14"},{"level":3,"text":"Fixed","anchor":"fixed","htmlText":"Fixed"},{"level":3,"text":"Added","anchor":"added","htmlText":"Added"},{"level":2,"text":"0.4.0 - 2026-07-14","anchor":"040---2026-07-14","htmlText":"0.4.0 - 2026-07-14"},{"level":3,"text":"Fixed","anchor":"fixed-1","htmlText":"Fixed"},{"level":3,"text":"Changed","anchor":"changed","htmlText":"Changed"},{"level":2,"text":"0.3.1 - 2026-07-11","anchor":"031---2026-07-11","htmlText":"0.3.1 - 2026-07-11"},{"level":3,"text":"Added","anchor":"added-1","htmlText":"Added"},{"level":3,"text":"Fixed","anchor":"fixed-2","htmlText":"Fixed"},{"level":3,"text":"Changed","anchor":"changed-1","htmlText":"Changed"},{"level":2,"text":"0.3.0 - 2026-07-09","anchor":"030---2026-07-09","htmlText":"0.3.0 - 2026-07-09"},{"level":3,"text":"Fixed","anchor":"fixed-3","htmlText":"Fixed"},{"level":3,"text":"Added","anchor":"added-2","htmlText":"Added"},{"level":3,"text":"Fixed","anchor":"fixed-4","htmlText":"Fixed"},{"level":2,"text":"0.2.0 - 2026-07-07","anchor":"020---2026-07-07","htmlText":"0.2.0 - 2026-07-07"},{"level":3,"text":"Removed","anchor":"removed","htmlText":"Removed"},{"level":3,"text":"Changed","anchor":"changed-2","htmlText":"Changed"},{"level":3,"text":"Added","anchor":"added-3","htmlText":"Added"},{"level":2,"text":"0.1.1 - 2026-06-12","anchor":"011---2026-06-12","htmlText":"0.1.1 - 2026-06-12"},{"level":2,"text":"0.1.0 - 2026-06-02","anchor":"010---2026-06-02","htmlText":"0.1.0 - 2026-06-02"}]},"issueTemplate":null,"discussionTemplate":null,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChangelog\u003c/h1\u003e\u003ca id=\"user-content-changelog\" class=\"anchor\" aria-label=\"Permalink: Changelog\" href=\"#changelog\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e0.5.0 - 2026-07-14\u003c/h2\u003e\u003ca id=\"user-content-050---2026-07-14\" class=\"anchor\" aria-label=\"Permalink: 0.5.0 - 2026-07-14\" href=\"#050---2026-07-14\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFixed\u003c/h3\u003e\u003ca id=\"user-content-fixed\" class=\"anchor\" aria-label=\"Permalink: Fixed\" href=\"#fixed\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eA tool the job merely \u003cem\u003enamed\u003c/em\u003e can no longer outrank the one that failed.\u003c/strong\u003e Found by\nrunning \u003ccode\u003eci explain\u003c/code\u003e over real failing runs from public repositories. Three of nine —\nencode/httpx, prefecthq/prefect and home-assistant/core — were decided by the job's cast\nlist rather than its cause of death:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003escripts/check\u003c/code\u003e-style CI shells run under \u003ccode\u003eset -x\u003c/code\u003e, so every command is echoed into\nthe log, passing or not. httpx's echo of \u003ccode\u003eruff check\u003c/code\u003e (a run that \u003cem\u003epassed\u003c/em\u003e), plus\n\u003ccode\u003eF401\u003c/code\u003e quoted inside ruff's non-fatal warning about a malformed noqa directive, made a\nplain \u003ccode\u003e1 failed, 1416 passed\u003c/code\u003e pytest failure come out as \u003ccode\u003epython_lint\u003c/code\u003e at 0.71.\u003c/li\u003e\n\u003cli\u003epip announces every dev dependency it resolves, so \u003ccode\u003eCollecting mypy==1.17.1\u003c/code\u003e puts\n\u003ccode\u003emypy\u003c/code\u003e in the log of a job that never type-checked anything. Prefect's pytest\ncollection error came out as \u003ccode\u003epython_type_check\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eSignals are now judged by the \u003cem\u003eline\u003c/em\u003e they land on: a rule whose every signal appears\nonly on a \u003ccode\u003eset -x\u003c/code\u003e echo, an Actions step header (\u003ccode\u003eRun …\u003c/code\u003e) or a pip install line has\nwatched a tool get named, never fail, and defers to a rule that matched a real error.\nScoring itself is unchanged, so an invocation sitting next to a genuine error still\ncorroborates it and keeps it at full confidence — a real dotnet, helm or php failure\nscores exactly as before. This generalises \u003ccode\u003eINVOCATION_ONLY_PATTERNS\u003c/code\u003e, which had to name\nevery tool one pattern at a time and switched itself off entirely as soon as a single\nsignal fell outside the list.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003e\u003ccode\u003epython_test_failure\u003c/code\u003e now recognises pytest's own verdict.\u003c/strong\u003e The rule could match a\n\u003cem\u003enamed\u003c/em\u003e failing test (\u003ccode\u003eFAILED x::y\u003c/code\u003e) or a bare \u003ccode\u003epytest\u003c/code\u003e invocation, but not\n\u003ccode\u003e===== 1 failed, 1416 passed in 18.37s =====\u003c/code\u003e, \u003ccode\u003eshort test summary info\u003c/code\u003e, or a\ncollection error (\u003ccode\u003eERROR tests/x.py - ValueError\u003c/code\u003e). A run that reported the count and\nnot the names — \u003ccode\u003e-q\u003c/code\u003e, or any plugin that rewrites the summary — was therefore carried by\nits invocation alone and lost to whatever tool the job had merely mentioned. The \u003ccode\u003e=\u003c/code\u003e\nrun and the \u003ccode\u003ein 12.3s\u003c/code\u003e tail are pytest's summary line and not jest's, so node test\nfailures are unaffected.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eANSI colour codes no longer hide the failure.\u003c/strong\u003e CI tools colour their output and CI\nkeeps the colour on (Airflow runs pytest with \u003ccode\u003e--color=yes\u003c/code\u003e, cargo honours\n\u003ccode\u003eCARGO_TERM_COLOR=always\u003c/code\u003e, jest and eslint colour by default), and the GitHub log API\nserves those escapes back with the ESC byte written out as the two literal characters\n\u003ccode\u003e^[\u003c/code\u003e. The colour reset lands \u003cem\u003einside\u003c/em\u003e the failure line — \u003ccode\u003e^[[31mFAILED^[[0m tests/…::…\u003c/code\u003e\n— so \u003ccode\u003eFAILED .*::\u003c/code\u003e and every other pattern spanning a coloured token silently stopped\nmatching. A real apache/airflow test failure was reported as \u003ccode\u003eartifact_or_cache_failure\u003c/code\u003e\nbecause the only signal left uncoloured was the bare \u003ccode\u003epytest\u003c/code\u003e invocation. Both\nencodings (real \u003ccode\u003e\\x1b\u003c/code\u003e and literalised \u003ccode\u003e^[\u003c/code\u003e) are now stripped before matching; the strip\nis anchored to the escape introducer, so \u003ccode\u003eerror[E0277]\u003c/code\u003e, \u003ccode\u003e[ERROR]\u003c/code\u003e and ordinary\nindexing are untouched.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003ePost-failure cleanup noise no longer outranks the real cause.\u003c/strong\u003e \u003ccode\u003eactions/upload-artifact\u003c/code\u003e\nappears in every job that uploads anything, and \"No files were found with the provided\npath\" is a \u003cem\u003ewarning\u003c/em\u003e it emits when its glob matches nothing (it says so itself: \"No\nartifacts will be uploaded\"). Together they fire on the commonest shape in CI — a test\nfails, and the \u003ccode\u003eif: failure()\u003c/code\u003e step uploading logs for diagnosis finds nothing — which\ntied the real cause and beat it on declaration order. A rule carried only by such\nsignals now defers to one that matched an actual error. A genuine artifact or cache\nfailure is unaffected: it trips a terminal signal (\"Failed to CreateArtifact\",\n\"Unable to download artifact\", \"Cache service responded with 500\").\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eThe classifier no longer reads a command that merely \u003cem\u003eran\u003c/em\u003e as the failure. Three\nbugs of the same shape, all found by running \u003ccode\u003eci explain\u003c/code\u003e over real failing runs\nfrom public repositories rather than over the fixture zoo:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e\\btsc\\b\u003c/code\u003e matched the x86 \u003cstrong\u003etime stamp counter\u003c/strong\u003e in the \u003ccode\u003eflags :\u003c/code\u003e line of\n\u003ccode\u003e/proc/cpuinfo\u003c/code\u003e, which perf-sensitive projects dump into their log preamble.\nA real rust-lang/rust build failure came back as \u003ccode\u003etypescript_typecheck\u003c/code\u003e on the\nstrength of a CPU feature name. \u003ccode\u003etsc\u003c/code\u003e now only counts in command position\n(\u003ccode\u003epnpm tsc\u003c/code\u003e, \u003ccode\u003e\u0026gt; tsc --noEmit\u003c/code\u003e, \u003ccode\u003enpx tsc\u003c/code\u003e, \u003ccode\u003etsc -p …\u003c/code\u003e) or before a flag/verb.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003edocker build\u003c/code\u003e / \u003ccode\u003edocker buildx build\u003c/code\u003e / \u003ccode\u003edocker compose\u003c/code\u003e appear in every job\nthat builds a container as a setup step, and \u003ccode\u003ecargo test\u003c/code\u003e / \u003ccode\u003eclippy\u003c/code\u003e appear in\nthe command line of every Rust CI job, passing or not. A rule matching \u003cem\u003eonly\u003c/em\u003e\nsuch signals now defers to a rule that matched an actual error, reusing the\ndeferral already in place for ambiguous network signals. They still count\ntoward confidence when a real error sits beside them, so a genuine docker or\nclippy failure is unchanged.\u003c/li\u003e\n\u003cli\u003eBecause scoring is by matched-pattern count, one bogus signal was enough to tie\nthe rule that matched the real error and beat it on declaration order alone.\nThe zoo missed all of this: its fixtures are clean, and a real log is not — the\nsame \u003ccode\u003eerror[E0277]\u003c/code\u003e that a fixture classifies correctly was misread in the wild\nbecause the job also happened to run \u003ccode\u003edocker buildx build\u003c/code\u003e.\nNo fixture changes classification or confidence (221 fixtures, top-1 1.0).\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAdded\u003c/h3\u003e\u003ca id=\"user-content-added\" class=\"anchor\" aria-label=\"Permalink: Added\" href=\"#added\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003epatchrail schema ci-classes\u003c/code\u003e now serves a published schema for\n\u003ccode\u003eci classes --format json\u003c/code\u003e, and the suite validates real output against it.\nIt was the one JSON command with no schema, no conformance test and no\ncookbook entry — which is why 0.4.0 could move it from\n\u003ccode\u003epatchrail.ci_classes.v1\u003c/code\u003e to \u003ccode\u003e.v2\u003c/code\u003e in a minor bump without anything going\nred, and why the break reached consumers (this project's own GitHub Action\namong them) silently. Changing the contract now means shipping the schema\nthat describes it: \u003ccode\u003etest_schema_conformance.py\u003c/code\u003e compares the \u003ccode\u003eschema_version\u003c/code\u003e\nthe CLI emits against the \u003ccode\u003econst\u003c/code\u003e in the schema a user can fetch, so the two\ncannot drift apart again. The schema also encodes the v2 rule itself —\n\u003ccode\u003eunknown\u003c/code\u003e is valid under \u003ccode\u003efallback\u003c/code\u003e and rejected inside \u003ccode\u003eclasses\u003c/code\u003e — so\nputting the sentinel back into the denominator fails validation.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003edocs/json-cookbook.md\u003c/code\u003e documents the \u003ccode\u003eci classes\u003c/code\u003e payload with a coverage\nrecipe (which supported classes has a log corpus never exercised?), and its\nsample output is pinned to the code by \u003ccode\u003etest_readme_claims.py\u003c/code\u003e in both\ndirections, like the README's counts.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e0.4.0 - 2026-07-14\u003c/h2\u003e\u003ca id=\"user-content-040---2026-07-14\" class=\"anchor\" aria-label=\"Permalink: 0.4.0 - 2026-07-14\" href=\"#040---2026-07-14\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eMinor bump rather than a patch: \u003ccode\u003eci classes --format json\u003c/code\u003e changes its contract.\n\u003ccode\u003eschema_version\u003c/code\u003e is now \u003ccode\u003epatchrail.ci_classes.v2\u003c/code\u003e and \u003ccode\u003eunknown\u003c/code\u003e left \u003ccode\u003eclasses\u003c/code\u003e\nand \u003ccode\u003ecount\u003c/code\u003e (see Fixed). Scripts pinned to the v1 shape need a one-line update.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFixed\u003c/h3\u003e\u003ca id=\"user-content-fixed-1\" class=\"anchor\" aria-label=\"Permalink: Fixed\" href=\"#fixed-1\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003epatchrail ci classes\u003c/code\u003e no longer counts \u003ccode\u003eunknown\u003c/code\u003e as a supported failure\nclass. It reported \"41 supported failure classes\" and listed \u003ccode\u003eunknown\u003c/code\u003e — with\na reproduction command — alongside the 40 real ones, contradicting the README,\nthe docs and the fixture benchmark, all of which say 40. \u003ccode\u003eunknown\u003c/code\u003e is what\n\u003ccode\u003eci explain\u003c/code\u003e returns when \u003cem\u003eno\u003c/em\u003e rule matches, so a coverage script following the\nREADME (\u003ccode\u003eci classes --format json\u003c/code\u003e) was dividing by a denominator containing an\nentry it could never cover. The sentinel is still reported, under a new\n\u003ccode\u003efallback\u003c/code\u003e key, and named in the text and markdown output; it is just out of\n\u003ccode\u003eclasses\u003c/code\u003e and \u003ccode\u003ecount\u003c/code\u003e. JSON consumers: \u003ccode\u003eschema_version\u003c/code\u003e is now\n\u003ccode\u003epatchrail.ci_classes.v2\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eREADME: the redaction bullet advertised 23 secret-redaction patterns; the\nshipped table has 24. The class, fixture and redaction counts the README\nadvertises are now derived from the code by \u003ccode\u003etests/test_readme_claims.py\u003c/code\u003e, so\nthey fail the build instead of going stale (the fixture count was already\npinned by tests, and it was the only one of the three that had stayed correct).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChanged\u003c/h3\u003e\u003ca id=\"user-content-changed\" class=\"anchor\" aria-label=\"Permalink: Changed\" href=\"#changed\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003epatchrail ci explain\u003c/code\u003e/\u003ccode\u003eclassify\u003c/code\u003e now print a first-use hint when the log\ninput is empty or whitespace-only. The common cause is the README one-liner\n\u003ccode\u003egh run view --log-failed | patchrail ci explain\u003c/code\u003e pointed at a run whose logs\nGitHub already expired (or a run that has not failed), which pipes in nothing.\nThe error keeps its exit code \u003ccode\u003e2\u003c/code\u003e and clean stdout; it just adds a line\ntelling the user to point it at a \u003cem\u003erecent\u003c/em\u003e failed run instead of leaving them\nguessing. Non-empty input is completely unaffected.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e0.3.1 - 2026-07-11\u003c/h2\u003e\u003ca id=\"user-content-031---2026-07-11\" class=\"anchor\" aria-label=\"Permalink: 0.3.1 - 2026-07-11\" href=\"#031---2026-07-11\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAdded\u003c/h3\u003e\u003ca id=\"user-content-added-1\" class=\"anchor\" aria-label=\"Permalink: Added\" href=\"#added-1\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003epatchrail ci explain\u003c/code\u003e/\u003ccode\u003eclassify\u003c/code\u003e now turn an \u003ccode\u003eunknown\u003c/code\u003e result into a\ncontribution on-ramp: the text and markdown reports append one line pointing\nthe maintainer at the \u003ccode\u003eci_failure_fixture\u003c/code\u003e issue template\n(\u003ccode\u003e.../issues/new?template=ci_failure_fixture.md\u003c/code\u003e) so an unrecognized log\nbecomes a fixture request instead of a dead-end. The classifier's behavior\nand JSON output are unchanged — the pointer is presentation-only and appears\nsolely when \u003ccode\u003efailure_class == \"unknown\"\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epatchrail -V\u003c/code\u003e is now a short alias for \u003ccode\u003e--version\u003c/code\u003e. Both print\n\u003ccode\u003epatchrail \u0026lt;version\u0026gt;\u003c/code\u003e and exit \u003ccode\u003e0\u003c/code\u003e, matching the conventional single-letter\nflag most CLIs expose (handy in bug reports and CI logs).\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003etests/test_schema_conformance.py\u003c/code\u003e validates real CLI output against\n\u003ccode\u003esrc/patchrail/schemas/*.v1.schema.json\u003c/code\u003e with \u003ccode\u003ejsonschema\u003c/code\u003e (dev-only\ndependency; the installed package still ships with zero runtime\ndependencies). Previously \u003ccode\u003e_load_schema()\u003c/code\u003e only read schema files as text\nto print them via \u003ccode\u003epatchrail ci schema\u003c/code\u003e; nothing checked that a payload\nbuilder's output still matched its schema. Covers \u003ccode\u003eci-result\u003c/code\u003e (every\nfixture in \u003ccode\u003eexamples/ci-triage/\u003c/code\u003e, 221 cases), \u003ccode\u003eci-benchmark\u003c/code\u003e, and\n\u003ccode\u003eci-fixture-check\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003emypy --strict\u003c/code\u003e now runs on \u003ccode\u003esrc/patchrail/ci/classify.py\u003c/code\u003e (the classifier\nengine) as a dev dependency and a CI step, alongside \u003ccode\u003eruff check\u003c/code\u003e/\u003ccode\u003eruff format --check\u003c/code\u003e. The module already passed strict type checking with no\nchanges required; this locks that in against regressions. See\n\u003ccode\u003e[tool.mypy]\u003c/code\u003e in \u003ccode\u003epyproject.toml\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eNew sanitized \u003ccode\u003egithub-actions-cmake-gcc-compile-error\u003c/code\u003e fixture covers a real\nCMake + g++ undeclared-identifier link failure for \u003ccode\u003ecpp_build_failure\u003c/code\u003e, which\npreviously had a classifier rule but no fixture in the benchmark zoo despite\nthe README advertising C++ support. Bringing the benchmark zoo to 220 cases.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ejava_build_failure\u003c/code\u003e now also recognises kotlinc's own diagnostic format\n(\u003ccode\u003ee: File.kt: (line, col): ...\u003c/code\u003e), \u003ccode\u003eUnresolved reference:\u003c/code\u003e, and Kotlin Gradle\ntask failures (\u003ccode\u003e:compileDebugKotlin FAILED\u003c/code\u003e). A maintainer pasting only the\nkotlinc excerpt of a Kotlin/Android CI failure — without the Gradle\n\u003ccode\u003eExecution failed for task\u003c/code\u003e / \u003ccode\u003eBUILD FAILED\u003c/code\u003e banner further down the log —\npreviously fell through to \u003ccode\u003eunknown\u003c/code\u003e at 0.15 confidence. New sanitized\n\u003ccode\u003egithub-actions-kotlin-compile-excerpt-no-banner\u003c/code\u003e fixture guards this,\nbringing the benchmark zoo to 221 cases.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFixed\u003c/h3\u003e\u003ca id=\"user-content-fixed-2\" class=\"anchor\" aria-label=\"Permalink: Fixed\" href=\"#fixed-2\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003epatchrail ci explain\u003c/code\u003e/\u003ccode\u003eclassify\u003c/code\u003e now normalize the GitHub Actions log line\nprefix before classifying, so the common one-liner\n\u003ccode\u003egh run view \u0026lt;run-id\u0026gt; --log-failed --repo \u0026lt;owner/repo\u0026gt; | patchrail ci explain\u003c/code\u003e\nclassifies identically to a saved raw log. \u003ccode\u003egh\u003c/code\u003e prefixes every line with\n\u003ccode\u003e\u0026lt;job\u0026gt;\\t\u0026lt;step\u0026gt;\\t\u0026lt;timestamp\u0026gt;\u003c/code\u003e (and a UTF-8 BOM on the first line), which shifted\nreal content off the start of the line and silently defeated the classifier's\nline-anchored (\u003ccode\u003e^\u003c/code\u003e) patterns — dropping confidence (e.g. \u003ccode\u003ego_lint\u003c/code\u003e and\n\u003ccode\u003enode_test_failure\u003c/code\u003e fell from \u003ccode\u003e0.95\u003c/code\u003e to \u003ccode\u003e0.89\u003c/code\u003e on sparse logs). The raw\nActions log-download form (\u003ccode\u003e\u0026lt;timestamp\u0026gt; \u0026lt;line\u0026gt;\u003c/code\u003e) is normalized too. Regression\ncases in \u003ccode\u003etests/test_ci_classify_expansion.py\u003c/code\u003e pin gh-prefixed == raw.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChanged\u003c/h3\u003e\u003ca id=\"user-content-changed-1\" class=\"anchor\" aria-label=\"Permalink: Changed\" href=\"#changed-1\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eExtracted the entire \u003ccode\u003efunded-issues\u003c/code\u003e subcommand group (20 argparse handlers,\n~50 markdown/text/CSV/JSONL renderers, and the argparse wiring for all 20\nsub-subcommands — 3853 of \u003ccode\u003ecli.py\u003c/code\u003e's 10368 lines) into a new\n\u003ccode\u003esrc/patchrail/cli_funded.py\u003c/code\u003e module, registered from \u003ccode\u003e_build_parser()\u003c/code\u003e via\n\u003ccode\u003ecli_funded.register(subparsers)\u003c/code\u003e. No behavior change: same commands, same\nflags, same output. \u003ccode\u003ecli.py\u003c/code\u003e drops from 10368 to ~5650 lines. If you import\n\u003ccode\u003epatchrail.cli._normalize_recheck_observation\u003c/code\u003e or similar funded-issues\ninternals directly (rather than going through the public CLI), import from\n\u003ccode\u003epatchrail.cli_funded\u003c/code\u003e instead.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e0.3.0 - 2026-07-09\u003c/h2\u003e\u003ca id=\"user-content-030---2026-07-09\" class=\"anchor\" aria-label=\"Permalink: 0.3.0 - 2026-07-09\" href=\"#030---2026-07-09\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFixed\u003c/h3\u003e\u003ca id=\"user-content-fixed-3\" class=\"anchor\" aria-label=\"Permalink: Fixed\" href=\"#fixed-3\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eDeterministic Go test failures are no longer misread as\n\u003ccode\u003enetwork_transient_failure\u003c/code\u003e when their logs contain incidental\nnetwork-shaped noise (\u003ccode\u003edial tcp\u003c/code\u003e, \u003ccode\u003econnection refused\u003c/code\u003e, \u003ccode\u003econtext deadline exceeded\u003c/code\u003e, \u003ccode\u003ei/o timeout\u003c/code\u003e). The classifier now defers a broad transient-network\nmatch built \u003cem\u003eentirely\u003c/em\u003e from these ambiguous signals to the concrete failure\nwhen one also matched, so a real bug isn't mislabeled \"just retry\". Genuine\noutages still classify as transient because they trip a terminal signal (DNS\nresolution, rate limit, gateway error, TLS handshake, or a git remote hang-up)\noutside the ambiguous set. \u003ccode\u003ego_test_failure\u003c/code\u003e also now recognises the canonical\n\u003ccode\u003e--- FAIL:\u003c/code\u003e marker. New \u003ccode\u003ego-integration-test-network-noise\u003c/code\u003e fixture guards this,\nbringing the benchmark zoo to 208 cases.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAdded\u003c/h3\u003e\u003ca id=\"user-content-added-2\" class=\"anchor\" aria-label=\"Permalink: Added\" href=\"#added-2\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003epatchrail --version\u003c/code\u003e now prints the installed version (e.g. \u003ccode\u003epatchrail 0.3.0\u003c/code\u003e)\nand exits, so a maintainer can confirm which release they are running without\ninvoking a subcommand.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ejava_build_failure\u003c/code\u003e now also recognises \u003cstrong\u003esbt\u003c/strong\u003e (Scala on the JVM). sbt prints\nnone of the Maven/Gradle banners the rule keyed on, so a genuine\n\u003ccode\u003e(project / Test / compileIncremental) Compilation failed\u003c/code\u003e — or an\n\u003ccode\u003esbt.TestsFailedException\u003c/code\u003e — previously fell through to \u003ccode\u003eunknown\u003c/code\u003e. New signals\ncover the sbt session banner, incremental-compile failure, Scala\n\u003ccode\u003enot found: value\u003c/code\u003e/\u003ccode\u003enot found: type\u003c/code\u003e errors, and the sbt test-failure\nexception; the reproduction command now suggests \u003ccode\u003esbt test\u003c/code\u003e. New sanitized\n\u003ccode\u003egithub-actions-sbt-scala-compile\u003c/code\u003e fixture (modelled on a real\n\u003ccode\u003escalatest/scalatest\u003c/code\u003e GitHub Actions run) guards this, bringing the benchmark\nzoo to 209 cases.\u003c/li\u003e\n\u003cli\u003eNew sanitized \u003ccode\u003eruby-rspec-parallel-failure\u003c/code\u003e fixture captures a real\n\u003ccode\u003erubocop/rubocop\u003c/code\u003e RSpec failure tail (parallel/turbo_tests summary with\n\u003ccode\u003epending\u003c/code\u003e before \u003ccode\u003efailures\u003c/code\u003e), bringing the benchmark zoo to 207 cases.\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003excode_build_failure\u003c/code\u003e class classifies Apple-platform build and test\nfailures from \u003ccode\u003excodebuild\u003c/code\u003e, \u003ccode\u003eswift build\u003c/code\u003e/\u003ccode\u003eswift test\u003c/code\u003e, and Swift Package\nManager — Swift compile errors, missing modules (\u003ccode\u003eerror: no such module\u003c/code\u003e),\nunresolved package dependencies, and XCTest failures (\u003ccode\u003e** BUILD FAILED **\u003c/code\u003e,\n\u003ccode\u003e** TEST FAILED **\u003c/code\u003e, \u003ccode\u003eThe following build commands failed:\u003c/code\u003e). Backed by three\nsanitized fixtures in \u003ccode\u003eexamples/ci-triage/\u003c/code\u003e, bringing the benchmark zoo to 169\ncases and the classifier to 40 failure classes.\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003edocs_build_failure\u003c/code\u003e class classifies documentation-site build failures\nfrom Sphinx (\u003ccode\u003esphinx-build -W\u003c/code\u003e warnings-as-errors, missing toctree entries),\nMkDocs (\u003ccode\u003emkdocs build --strict\u003c/code\u003e broken links), and Docusaurus (\u003ccode\u003edocusaurus build\u003c/code\u003e broken links). Backed by three sanitized fixtures in\n\u003ccode\u003eexamples/ci-triage/\u003c/code\u003e, bringing the benchmark zoo to 166 cases.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epatchrail ci classes\u003c/code\u003e lists every supported failure class with its likely\nsubsystem and reproduction command (plus the \u003ccode\u003eunknown\u003c/code\u003e fallback), in stable\norder. Supports \u003ccode\u003e--format text|json|markdown\u003c/code\u003e and \u003ccode\u003e--out\u003c/code\u003e, so the set of\nclasses the classifier can diagnose is discoverable from the CLI instead of\nonly in the source. Closes #150.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFixed\u003c/h3\u003e\u003ca id=\"user-content-fixed-4\" class=\"anchor\" aria-label=\"Permalink: Fixed\" href=\"#fixed-4\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eReal RSpec failures now classify as \u003ccode\u003eruby_bundle_failure\u003c/code\u003e instead of\n\u003ccode\u003eunknown\u003c/code\u003e. RSpec prints its rerun list as \u003ccode\u003erspec ./path/to/thing_spec.rb[…]\u003c/code\u003e\nand its summary as \u003ccode\u003eN examples, [K pending, ]M failures\u003c/code\u003e (rspec, parallel and\nturbo_tests) — neither of which the old \u003ccode\u003erspec .*failures?\u003c/code\u003e pattern matched,\nso a pasted spec-failure tail without bundler setup lines fell through to\n\u003ccode\u003eunknown\u003c/code\u003e. Two shape-matching patterns were added to the rule. Surfaced by\ndogfooding a real \u003ccode\u003erubocop/rubocop\u003c/code\u003e CI run.\u003c/li\u003e\n\u003cli\u003ePython CI logs no longer misclassify as \u003ccode\u003epython_dependency_resolution\u003c/code\u003e just\nbecause they run \u003ccode\u003epython -m pip install\u003c/code\u003e. That bare command line was a\ndetection pattern, but it appears in almost every Python CI job regardless of\nwhat actually failed, so any failing Python job with no stronger signal was\nreported as a dependency-resolution conflict with the misleading \"pin or relax\nthe conflicting dependency range\" advice. Dogfooded against a real\n\u003ccode\u003epandas-dev/pandas\u003c/code\u003e 32-bit CI run whose \u003ccode\u003epip install\u003c/code\u003e failed at\n\u003ccode\u003emetadata-generation-failed\u003c/code\u003e (a package build error, \u003ccode\u003eRust not found\u003c/code\u003e) — it was\nreported as \u003ccode\u003epython_dependency_resolution\u003c/code\u003e (0.53). The boilerplate pattern is\ndropped, so a build/metadata failure with no genuine resolution signal now\nstays honest (\u003ccode\u003eunknown\u003c/code\u003e) instead. To keep recall on real conflicts, two\ngenuine pip signals were added: pip's actual Requires-Python wording\n(\u003ccode\u003erequires a different Python:\u003c/code\u003e) and its no-distribution \u003ccode\u003e(from versions: …)\u003c/code\u003e\nline; the three synthetic no-matching-distribution fixtures were updated to\ninclude the real \u003ccode\u003e(from versions: …)\u003c/code\u003e output pip prints. Benchmark stays at\n206/206 top-1 with all confidence floors met; the bundled dependency-failure\ndemo now reports 0.89 (three genuine resolution signals) instead of 0.95.\nRegression covered in \u003ccode\u003etests/\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epatchrail ci explain\u003c/code\u003e/\u003ccode\u003eclassify\u003c/code\u003e no longer hangs on large CI logs. The\n\u003ccode\u003egithub_actions_workflow\u003c/code\u003e rule paired two unanchored lookaheads\n(\u003ccode\u003e(?=[\\s\\S]*.github/workflows/…)(?=[\\s\\S]*Invalid workflow file…)\u003c/code\u003e); under\n\u003ccode\u003ere.search\u003c/code\u003e that compound is retried at every start position, so a log that\nmentions \u003ccode\u003e.github/workflows/*.yml\u003c/code\u003e (every \u003ccode\u003eactions/checkout\u003c/code\u003e step does) but not\na workflow-error phrase drove the matcher into O(n²) backtracking and pegged a\ncore at 100% for minutes. Dogfooded against a real \u003ccode\u003ecli/cli\u003c/code\u003e Go CI run\n(~200 KB) that never returned. The lookahead is now anchored with \u003ccode\u003e\\A\u003c/code\u003e so it is\nevaluated once, in linear time; the \"workflow path AND error phrase present\"\nsignal is unchanged. Regression covered in \u003ccode\u003etests/\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eRust CI failures no longer misclassify as \u003ccode\u003enode_dependency_install\u003c/code\u003e,\n\u003ccode\u003edotnet_build_failure\u003c/code\u003e, or \u003ccode\u003ejava_build_failure\u003c/code\u003e because of generic boilerplate.\nThe \u003ccode\u003eSwatinem/rust-cache\u003c/code\u003e action prints \u003ccode\u003eLockfiles considered:\u003c/code\u003e (which matched\nthe old bare \u003ccode\u003elockfile\u003c/code\u003e node signal) and cargo prints \u003ccode\u003ebuild failed, waiting for other jobs to finish\u003c/code\u003e (which matched the case-insensitive \u003ccode\u003eBuild FAILED\u003c/code\u003e /\n\u003ccode\u003eBUILD FAILED\u003c/code\u003e banners). The node lockfile signal now requires a whole-word\n\u003ccode\u003elockfile\u003c/code\u003e, and the .NET/Gradle banners are matched case-sensitively so they\nfire only on the tool's actual \u003ccode\u003eBuild FAILED\u003c/code\u003e / \u003ccode\u003eBUILD FAILED\u003c/code\u003e output. A real\n\u003ccode\u003etokio-rs/tokio\u003c/code\u003e rustdoc failure (\u003ccode\u003eerror[E0433]\u003c/code\u003e) now classifies as\n\u003ccode\u003erust_test_failure\u003c/code\u003e. Regression covered in \u003ccode\u003etests/\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eSharper reproduce commands for three failure classes surfaced by \u003ccode\u003epatchrail ci classes\u003c/code\u003e / \u003ccode\u003eci explain\u003c/code\u003e. \u003ccode\u003enode_script_missing\u003c/code\u003e no longer suggests \u003ccode\u003enpm run build\u003c/code\u003e (which just re-triggers the \"missing script\" error) and instead runs\n\u003ccode\u003enpm run\u003c/code\u003e to list the scripts \u003ccode\u003epackage.json\u003c/code\u003e actually defines, so you can\ncompare against the one your workflow calls. \u003ccode\u003esecurity_scan_failure\u003c/code\u003e names the\nconcrete scanners to rerun locally (\u003ccode\u003enpm audit\u003c/code\u003e, \u003ccode\u003epip-audit\u003c/code\u003e, \u003ccode\u003ecargo audit\u003c/code\u003e,\n\u003ccode\u003etrivy fs .\u003c/code\u003e, \u003ccode\u003ebandit -r .\u003c/code\u003e, \u003ccode\u003esemgrep --config auto\u003c/code\u003e) instead of the generic\n\"rerun the failing security scan locally\". \u003ccode\u003egithub_actions_workflow\u003c/code\u003e points at\n\u003ccode\u003eactionlint .github/workflows/\u003c/code\u003e, which validates workflow syntax and action\nrefs locally, rather than only printing the YAML back with \u003ccode\u003egh workflow view\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eReal GitHub Actions logs no longer misclassify as \u003ccode\u003egit_checkout_failure\u003c/code\u003e when\ncheckout actually succeeded. The rule dropped three boilerplate signals that\nappear in almost every Actions log regardless of outcome — the \u003ccode\u003eactions/checkout\u003c/code\u003e\nsetup step, the \u003ccode\u003egit submodule foreach\u003c/code\u003e post-job cleanup line, and a bare\n\u003ccode\u003egit-lfs\u003c/code\u003e mention — keeping only genuine checkout/clone/submodule/LFS \u003cem\u003efailure\u003c/em\u003e\nmarkers (\u003ccode\u003efatal: ...\u003c/code\u003e, \u003ccode\u003eFailed to fetch submodule\u003c/code\u003e, \u003ccode\u003esmudge filter lfs failed\u003c/code\u003e,\n\u003ccode\u003eerror downloading object\u003c/code\u003e, …). Dogfooded against a real \u003ccode\u003epallets/flask\u003c/code\u003e CI run\nwhose pytest jobs failed on a conftest \u003ccode\u003eSyntaxError\u003c/code\u003e but were reported as a git\ncheckout problem.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epython_test_failure\u003c/code\u003e now also recognizes pytest collection failures\n(\u003ccode\u003eImportError while loading conftest ...\u003c/code\u003e, \u003ccode\u003eN errors during collection\u003c/code\u003e), so a\nbroken \u003ccode\u003econftest.py\u003c/code\u003e or import-time error surfaces as a test failure with the\n\u003ccode\u003epython -m pytest -q\u003c/code\u003e reproduce line instead of falling through to a weaker or\nwrong class.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epatchrail ci explain\u003c/code\u003e and \u003ccode\u003eci classify\u003c/code\u003e now fail clearly on empty or\nwhitespace-only input (from \u003ccode\u003e--log\u003c/code\u003e or stdin) instead of silently reporting\n\u003ccode\u003efailure_class: unknown\u003c/code\u003e with confidence \u003ccode\u003e0.15\u003c/code\u003e and exit code \u003ccode\u003e0\u003c/code\u003e. They print\n\u003ccode\u003elog input is empty\u003c/code\u003e to stderr, exit with code \u003ccode\u003e2\u003c/code\u003e, and write nothing to\n\u003ccode\u003e--out\u003c/code\u003e, so a bad shell redirect is no longer mistaken for an unclassifiable\nlog. Closes #151.\u003c/li\u003e\n\u003cli\u003eAdded \u003ccode\u003enode_script_missing\u003c/code\u003e to the published \u003ccode\u003eci-result\u003c/code\u003e schema enum; the\nclassifier could already emit it, so a valid classification previously failed\nschema validation for downstream consumers. A new test guards that every rule\nclass is declared in the schema enum.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e0.2.0 - 2026-07-07\u003c/h2\u003e\u003ca id=\"user-content-020---2026-07-07\" class=\"anchor\" aria-label=\"Permalink: 0.2.0 - 2026-07-07\" href=\"#020---2026-07-07\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRemoved\u003c/h3\u003e\u003ca id=\"user-content-removed\" class=\"anchor\" aria-label=\"Permalink: Removed\" href=\"#removed\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRemoved the commercial \u003ccode\u003eGuide:\u003c/code\u003e link that \u003ccode\u003eci explain\u003c/code\u003e appended to text and\nMarkdown reports, and the matching guide URL outputs from the GitHub Action.\nReports now end after the classification; per-class remediation write-ups\nlive in-repo under \u003ccode\u003edocs/fix/\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eRemoved commercial product links and campaign-tagged URLs from the README,\ndocs, and the PyPI project URL list.\u003c/li\u003e\n\u003cli\u003eRemoved the distribution and web-metrics tooling (\u003ccode\u003eci share-links\u003c/code\u003e and the\nweb metrics commands and store). PatchRail no longer ships link-tracking or\ndistribution helpers.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChanged\u003c/h3\u003e\u003ca id=\"user-content-changed-2\" class=\"anchor\" aria-label=\"Permalink: Changed\" href=\"#changed-2\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003efunded-issues\u003c/code\u003e is now explicitly labeled experimental. Discovery commands\ndefault to safe-only filtering, and risky entries require an explicit\n\u003ccode\u003e--include-risky\u003c/code\u003e flag.\u003c/li\u003e\n\u003cli\u003eRewrote the README around the open-source CI triage workflow: quickstart\nwith real classifier output, honest feature table, local-first safety\nsection, and the fixture contribution path.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAdded\u003c/h3\u003e\u003ca id=\"user-content-added-3\" class=\"anchor\" aria-label=\"Permalink: Added\" href=\"#added-3\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eAdded \u003ccode\u003enode_script_missing\u003c/code\u003e CI classification so npm/pnpm/yarn jobs that\ncall a missing package script are separated from dependency-install failures\nand routed to a workflow/script repair path.\u003c/li\u003e\n\u003cli\u003eAdded a permanent source-level blocklist to the funded-issues tracker:\nowners manually verified as fake-bounty sources are dropped at the\n\u003ccode\u003emerge_into_store\u003c/code\u003e choke point (counted as \u003ccode\u003eblocked\u003c/code\u003e in the merge summary)\nand \u003ccode\u003epurge_blocklisted_entries\u003c/code\u003e removes any legacy entries; \u003ccode\u003etrack\u003c/code\u003e runs the\npurge on every merge so existing stores self-heal.\u003c/li\u003e\n\u003cli\u003eAdded \u003ccode\u003efunded-issues import-algora-board\u003c/code\u003e, an offline parser for a locally\nsaved Algora organization bounty-board page. It extracts the funder-stated\nUSD amount, GitHub issue reference, posting age, and declared claim count\nper bounty, and can merge the scored records into a tracker store. No\nnetwork access is performed.\u003c/li\u003e\n\u003cli\u003eAdded read-only competition and payout-vs-effort scoring signals plus the\n\u003ccode\u003efunded-issues competition\u003c/code\u003e and \u003ccode\u003efunded-issues payout-effort\u003c/code\u003e batch\ncommands, all derived from public metadata observations with no claims,\ncomments, or maintainer contact.\u003c/li\u003e\n\u003cli\u003eAdded an offline owner-level \u003ccode\u003esource_noise\u003c/code\u003e heuristic and\n\u003ccode\u003efunded-issues apply-recheck\u003c/code\u003e, a local-file-only command that transitions\ntracker entries to closed / stale / active from recheck observations.\u003c/li\u003e\n\u003cli\u003eAdded .NET/NuGet/C# and xUnit fixture coverage for \u003ccode\u003edotnet restore\u003c/code\u003e,\n\u003ccode\u003edotnet build\u003c/code\u003e, and \u003ccode\u003edotnet test\u003c/code\u003e failure modes, growing the public CI\nfixture zoo to 153 cases.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e0.1.1 - 2026-06-12\u003c/h2\u003e\u003ca id=\"user-content-011---2026-06-12\" class=\"anchor\" aria-label=\"Permalink: 0.1.1 - 2026-06-12\" href=\"#011---2026-06-12\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eci explain\u003c/code\u003e now ends text and Markdown reports with a \u003ccode\u003eGuide:\u003c/code\u003e link to the\nmatching getpatchrail.com \u003ccode\u003e/fix\u003c/code\u003e remediation page; unknown or unpublished\nfailure classes fall back to the \u003ccode\u003e/fix\u003c/code\u003e index without a network call.\u003c/li\u003e\n\u003cli\u003eAdded \u003ccode\u003efunded-issues fresh\u003c/code\u003e, a local read-only radar over the tracker store\nthat surfaces recently posted or recently labeled funded issues for fast\nsolver-side triage.\u003c/li\u003e\n\u003cli\u003eAdded \u003ccode\u003epre_commit_hook_failure\u003c/code\u003e CI classification so pre-commit hook output is\nrecognized directly while the CLI still avoids linking to a missing \u003ccode\u003e/fix\u003c/code\u003e\npage until that guide exists.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e0.1.0 - 2026-06-02\u003c/h2\u003e\u003ca id=\"user-content-010---2026-06-02\" class=\"anchor\" aria-label=\"Permalink: 0.1.0 - 2026-06-02\" href=\"#010---2026-06-02\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eInitial public CI Janitor snapshot.\u003c/li\u003e\n\u003cli\u003eAdded \u003ccode\u003epatchrail ci explain\u003c/code\u003e and \u003ccode\u003epatchrail ci classify\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eAdded local Markdown, JSON, and text reports.\u003c/li\u003e\n\u003cli\u003eAdded Apache-2.0 license and safety/ethics documentation.\u003c/li\u003e\n\u003cli\u003eAdded fixture-backed tests, local benchmark command, and GitHub Actions CI.\u003c/li\u003e\n\u003cli\u003eExpanded the initial CI fixture zoo to 101 sanitized synthetic examples across\nPython, Node, TypeScript, Go, Rust, and GitHub Actions failure modes.\u003c/li\u003e\n\u003cli\u003eAdded a read-only GitHub Actions triage artifact workflow.\u003c/li\u003e\n\u003cli\u003eAdded the experimental local Agent Control Plane queue with SQLite-backed\nwork items, approval states, audit export, CI result import, and proposal\nrecords.\u003c/li\u003e\n\u003cli\u003eAdded the experimental read-only \u003ccode\u003efunded-issues\u003c/code\u003e CLI over local metadata,\nwith safe-only filtering and explicit anti-abuse blocked actions.\u003c/li\u003e\n\u003cli\u003eAdded permission-only adopter reporting and a public metrics tracker for\npilot outcomes, adoption signals, and open-source program evidence gaps.\u003c/li\u003e\n\u003cli\u003eAdded release-prep evidence docs, package smoke checks, and manual publish\ngates. Release tags, PyPI publishing, GitHub Releases, and public\nannouncements remain maintainer actions.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/article\u003e","richTextTruncated":false,"renderedFileInfo":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"Changelog","fully_qualified_name":"Changelog","kind":"section_1","ident_start":2,"ident_end":11,"extent_start":0,"extent_end":25775,"ident_utf16":{"start":{"line_number":0,"utf16_col":2},"end":{"line_number":0,"utf16_col":11}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":409,"utf16_col":0}}},{"name":"0.5.0 - 2026-07-14","fully_qualified_name":"0.5.0 - 2026-07-14","kind":"section_2","ident_start":16,"ident_end":34,"extent_start":13,"extent_end":6664,"ident_utf16":{"start":{"line_number":2,"utf16_col":3},"end":{"line_number":2,"utf16_col":21}},"extent_utf16":{"start":{"line_number":2,"utf16_col":0},"end":{"line_number":95,"utf16_col":0}}},{"name":"Fixed","fully_qualified_name":"Fixed","kind":"section_3","ident_start":40,"ident_end":45,"extent_start":36,"extent_end":5503,"ident_utf16":{"start":{"line_number":4,"utf16_col":4},"end":{"line_number":4,"utf16_col":9}},"extent_utf16":{"start":{"line_number":4,"utf16_col":0},"end":{"line_number":76,"utf16_col":0}}},{"name":"Added","fully_qualified_name":"Added","kind":"section_3","ident_start":5507,"ident_end":5512,"extent_start":5503,"extent_end":6664,"ident_utf16":{"start":{"line_number":76,"utf16_col":4},"end":{"line_number":76,"utf16_col":9}},"extent_utf16":{"start":{"line_number":76,"utf16_col":0},"end":{"line_number":95,"utf16_col":0}}},{"name":"0.4.0 - 2026-07-14","fully_qualified_name":"0.4.0 - 2026-07-14","kind":"section_2","ident_start":6667,"ident_end":6685,"extent_start":6664,"extent_end":8594,"ident_utf16":{"start":{"line_number":95,"utf16_col":3},"end":{"line_number":95,"utf16_col":21}},"extent_utf16":{"start":{"line_number":95,"utf16_col":0},"end":{"line_number":129,"utf16_col":0}}},{"name":"Fixed","fully_qualified_name":"Fixed","kind":"section_3","ident_start":6932,"ident_end":6937,"extent_start":6928,"extent_end":8057,"ident_utf16":{"start":{"line_number":101,"utf16_col":4},"end":{"line_number":101,"utf16_col":9}},"extent_utf16":{"start":{"line_number":101,"utf16_col":0},"end":{"line_number":119,"utf16_col":0}}},{"name":"Changed","fully_qualified_name":"Changed","kind":"section_3","ident_start":8061,"ident_end":8068,"extent_start":8057,"extent_end":8594,"ident_utf16":{"start":{"line_number":119,"utf16_col":4},"end":{"line_number":119,"utf16_col":11}},"extent_utf16":{"start":{"line_number":119,"utf16_col":0},"end":{"line_number":129,"utf16_col":0}}},{"name":"0.3.1 - 2026-07-11","fully_qualified_name":"0.3.1 - 2026-07-11","kind":"section_2","ident_start":8597,"ident_end":8615,"extent_start":8594,"extent_end":12475,"ident_utf16":{"start":{"line_number":129,"utf16_col":3},"end":{"line_number":129,"utf16_col":21}},"extent_utf16":{"start":{"line_number":129,"utf16_col":0},"end":{"line_number":194,"utf16_col":0}}},{"name":"Added","fully_qualified_name":"Added","kind":"section_3","ident_start":8621,"ident_end":8626,"extent_start":8617,"extent_end":11059,"ident_utf16":{"start":{"line_number":131,"utf16_col":4},"end":{"line_number":131,"utf16_col":9}},"extent_utf16":{"start":{"line_number":131,"utf16_col":0},"end":{"line_number":169,"utf16_col":0}}},{"name":"Fixed","fully_qualified_name":"Fixed","kind":"section_3","ident_start":11063,"ident_end":11068,"extent_start":11059,"extent_end":11823,"ident_utf16":{"start":{"line_number":169,"utf16_col":4},"end":{"line_number":169,"utf16_col":9}},"extent_utf16":{"start":{"line_number":169,"utf16_col":0},"end":{"line_number":182,"utf16_col":0}}},{"name":"Changed","fully_qualified_name":"Changed","kind":"section_3","ident_start":11827,"ident_end":11834,"extent_start":11823,"extent_end":12475,"ident_utf16":{"start":{"line_number":182,"utf16_col":4},"end":{"line_number":182,"utf16_col":11}},"extent_utf16":{"start":{"line_number":182,"utf16_col":0},"end":{"line_number":194,"utf16_col":0}}},{"name":"0.3.0 - 2026-07-09","fully_qualified_name":"0.3.0 - 2026-07-09","kind":"section_2","ident_start":12478,"ident_end":12496,"extent_start":12475,"extent_end":21481,"ident_utf16":{"start":{"line_number":194,"utf16_col":3},"end":{"line_number":194,"utf16_col":21}},"extent_utf16":{"start":{"line_number":194,"utf16_col":0},"end":{"line_number":328,"utf16_col":0}}},{"name":"Fixed","fully_qualified_name":"Fixed","kind":"section_3","ident_start":12502,"ident_end":12507,"extent_start":12498,"extent_end":13313,"ident_utf16":{"start":{"line_number":196,"utf16_col":4},"end":{"line_number":196,"utf16_col":9}},"extent_utf16":{"start":{"line_number":196,"utf16_col":0},"end":{"line_number":210,"utf16_col":0}}},{"name":"Added","fully_qualified_name":"Added","kind":"section_3","ident_start":13317,"ident_end":13322,"extent_start":13313,"extent_end":15637,"ident_utf16":{"start":{"line_number":210,"utf16_col":4},"end":{"line_number":210,"utf16_col":9}},"extent_utf16":{"start":{"line_number":210,"utf16_col":0},"end":{"line_number":246,"utf16_col":0}}},{"name":"Fixed","fully_qualified_name":"Fixed","kind":"section_3","ident_start":15641,"ident_end":15646,"extent_start":15637,"extent_end":21481,"ident_utf16":{"start":{"line_number":246,"utf16_col":4},"end":{"line_number":246,"utf16_col":9}},"extent_utf16":{"start":{"line_number":246,"utf16_col":0},"end":{"line_number":328,"utf16_col":0}}},{"name":"0.2.0 - 2026-07-07","fully_qualified_name":"0.2.0 - 2026-07-07","kind":"section_2","ident_start":21484,"ident_end":21502,"extent_start":21481,"extent_end":23994,"ident_utf16":{"start":{"line_number":328,"utf16_col":3},"end":{"line_number":328,"utf16_col":21}},"extent_utf16":{"start":{"line_number":328,"utf16_col":0},"end":{"line_number":377,"utf16_col":0}}},{"name":"Removed","fully_qualified_name":"Removed","kind":"section_3","ident_start":21508,"ident_end":21515,"extent_start":21504,"extent_end":22080,"ident_utf16":{"start":{"line_number":330,"utf16_col":4},"end":{"line_number":330,"utf16_col":11}},"extent_utf16":{"start":{"line_number":330,"utf16_col":0},"end":{"line_number":342,"utf16_col":0}}},{"name":"Changed","fully_qualified_name":"Changed","kind":"section_3","ident_start":22084,"ident_end":22091,"extent_start":22080,"extent_end":22462,"ident_utf16":{"start":{"line_number":342,"utf16_col":4},"end":{"line_number":342,"utf16_col":11}},"extent_utf16":{"start":{"line_number":342,"utf16_col":0},"end":{"line_number":351,"utf16_col":0}}},{"name":"Added","fully_qualified_name":"Added","kind":"section_3","ident_start":22466,"ident_end":22471,"extent_start":22462,"extent_end":23994,"ident_utf16":{"start":{"line_number":351,"utf16_col":4},"end":{"line_number":351,"utf16_col":9}},"extent_utf16":{"start":{"line_number":351,"utf16_col":0},"end":{"line_number":377,"utf16_col":0}}},{"name":"0.1.1 - 2026-06-12","fully_qualified_name":"0.1.1 - 2026-06-12","kind":"section_2","ident_start":23997,"ident_end":24015,"extent_start":23994,"extent_end":24609,"ident_utf16":{"start":{"line_number":377,"utf16_col":3},"end":{"line_number":377,"utf16_col":21}},"extent_utf16":{"start":{"line_number":377,"utf16_col":0},"end":{"line_number":389,"utf16_col":0}}},{"name":"0.1.0 - 2026-06-02","fully_qualified_name":"0.1.0 - 2026-06-02","kind":"section_2","ident_start":24612,"ident_end":24630,"extent_start":24609,"extent_end":25775,"ident_utf16":{"start":{"line_number":389,"utf16_col":3},"end":{"line_number":389,"utf16_col":21}},"extent_utf16":{"start":{"line_number":389,"utf16_col":0},"end":{"line_number":409,"utf16_col":0}}}]}},"codeViewLayoutRoute":{"repo":{"id":1257620736,"defaultBranch":"main","name":"patchrail","ownerLogin":"patchrail","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2026-06-02T21:15:48.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/284771939?v=4","public":true,"private":false,"isOrgOwned":true,"isArchived":false},"currentUser":null,"uploadToken":"car3muyphxwEBLOST0LFIyhg4ThmyHZCLZ3obzUxybFqBp7Cx4kri-35QBZ1OqDdK1rQXOWH6aVy92v3ViTUgQ","allShortcutsEnabled":false,"treeExpanded":true,"path":"CHANGELOG.md","symbolsExpanded":false,"refInfo":{"name":"v0.5.0","listCacheKey":"v0:1784794624.0","canEdit":false,"currentOid":"4e063b241f79b85e3bae7df37454edd6257dfea2"},"helpUrl":"https://docs.github.com","githubDevUrl":null},"codeViewFileTreeLayoutRoute":{"fileTree":{"":{"items":[{"name":".agents","path":".agents","contentType":"directory"},{"name":".github","path":".github","contentType":"directory"},{"name":"actions","path":"actions","contentType":"directory"},{"name":"docs","path":"docs","contentType":"directory"},{"name":"examples","path":"examples","contentType":"directory"},{"name":"schemas","path":"schemas","contentType":"directory"},{"name":"scripts","path":"scripts","contentType":"directory"},{"name":"src","path":"src","contentType":"directory"},{"name":"tests","path":"tests","contentType":"directory"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":"ADOPTERS.md","path":"ADOPTERS.md","contentType":"file"},{"name":"AGENTS.md","path":"AGENTS.md","contentType":"file"},{"name":"CHANGELOG.md","path":"CHANGELOG.md","contentType":"file"},{"name":"CODE_OF_CONDUCT.md","path":"CODE_OF_CONDUCT.md","contentType":"file"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","contentType":"file"},{"name":"ETHICS.md","path":"ETHICS.md","contentType":"file"},{"name":"GOVERNANCE.md","path":"GOVERNANCE.md","contentType":"file"},{"name":"LICENSE","path":"LICENSE","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"SECURITY.md","path":"SECURITY.md","contentType":"file"},{"name":"pyproject.toml","path":"pyproject.toml","contentType":"file"},{"name":"uv.lock","path":"uv.lock","contentType":"file"}],"totalCount":22}},"fileTreeProcessingTime":67.949459,"foldersToFetch":[]},"codeViewBlobLayoutRoute":{"codeLineWrapEnabled":false,"refInfo":{"name":"v0.5.0","listCacheKey":"v0:1784794624.0","canEdit":false,"refType":"tag","currentOid":"4e063b241f79b85e3bae7df37454edd6257dfea2","canEditOnDefaultBranch":false,"fileExistsOnDefault":true},"path":"CHANGELOG.md","blob":{"copilotSWEAgentEnabled":false,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/patchrail/patchrail/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"CHANGELOG.md","displayUrl":"https://github.com/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md?raw=true","headerInfo":{"blobSize":"25.2 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":null,"isGitLfs":false,"onBranch":false,"shortPath":"1acb600","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fpatchrail%2Fpatchrail%2Fblob%2Fv0.5.0%2FCHANGELOG.md","isCSV":false,"isRichtext":true,"lineInfo":{"truncatedLoc":"409","truncatedSloc":"372"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"isIssueTemplate":false,"isDiscussionTemplate":false,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/patchrail/patchrail/blob/v0.5.0/CHANGELOG.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/patchrail/patchrail/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/patchrail/patchrail/raw/refs/tags/v0.5.0/CHANGELOG.md","renderImageOrRaw":false,"shortPath":null,"symbolsEnabled":true,"tabSize":4,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null},"copilotInfo":null,"copilotAccessAllowed":false,"copilotSpacesEnabled":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"isMarketplaceEnabled":true},"codeViewBlobLayoutRoute.StyledBlob":{"rawLines":["# Changelog","","## 0.5.0 - 2026-07-14","","### Fixed","","- **A tool the job merely *named* can no longer outrank the one that failed.** Found by","  running `ci explain` over real failing runs from public repositories. Three of nine —","  encode/httpx, prefecthq/prefect and home-assistant/core — were decided by the job's cast","  list rather than its cause of death:","  - `scripts/check`-style CI shells run under `set -x`, so every command is echoed into","    the log, passing or not. httpx's echo of `ruff check` (a run that *passed*), plus","    `F401` quoted inside ruff's non-fatal warning about a malformed noqa directive, made a","    plain `1 failed, 1416 passed` pytest failure come out as `python_lint` at 0.71.","  - pip announces every dev dependency it resolves, so `Collecting mypy==1.17.1` puts","    `mypy` in the log of a job that never type-checked anything. Prefect's pytest","    collection error came out as `python_type_check`.","","  Signals are now judged by the *line* they land on: a rule whose every signal appears","  only on a `set -x` echo, an Actions step header (`Run …`) or a pip install line has","  watched a tool get named, never fail, and defers to a rule that matched a real error.","  Scoring itself is unchanged, so an invocation sitting next to a genuine error still","  corroborates it and keeps it at full confidence — a real dotnet, helm or php failure","  scores exactly as before. This generalises `INVOCATION_ONLY_PATTERNS`, which had to name","  every tool one pattern at a time and switched itself off entirely as soon as a single","  signal fell outside the list.","- **`python_test_failure` now recognises pytest's own verdict.** The rule could match a","  *named* failing test (`FAILED x::y`) or a bare `pytest` invocation, but not","  `===== 1 failed, 1416 passed in 18.37s =====`, `short test summary info`, or a","  collection error (`ERROR tests/x.py - ValueError`). A run that reported the count and","  not the names — `-q`, or any plugin that rewrites the summary — was therefore carried by","  its invocation alone and lost to whatever tool the job had merely mentioned. The `=`","  run and the `in 12.3s` tail are pytest's summary line and not jest's, so node test","  failures are unaffected.","- **ANSI colour codes no longer hide the failure.** CI tools colour their output and CI","  keeps the colour on (Airflow runs pytest with `--color=yes`, cargo honours","  `CARGO_TERM_COLOR=always`, jest and eslint colour by default), and the GitHub log API","  serves those escapes back with the ESC byte written out as the two literal characters","  `^[`. The colour reset lands *inside* the failure line — `^[[31mFAILED^[[0m tests/…::…`","  — so `FAILED .*::` and every other pattern spanning a coloured token silently stopped","  matching. A real apache/airflow test failure was reported as `artifact_or_cache_failure`","  because the only signal left uncoloured was the bare `pytest` invocation. Both","  encodings (real `\\x1b` and literalised `^[`) are now stripped before matching; the strip","  is anchored to the escape introducer, so `error[E0277]`, `[ERROR]` and ordinary","  indexing are untouched.","- **Post-failure cleanup noise no longer outranks the real cause.** `actions/upload-artifact`","  appears in every job that uploads anything, and \"No files were found with the provided","  path\" is a *warning* it emits when its glob matches nothing (it says so itself: \"No","  artifacts will be uploaded\"). Together they fire on the commonest shape in CI — a test","  fails, and the `if: failure()` step uploading logs for diagnosis finds nothing — which","  tied the real cause and beat it on declaration order. A rule carried only by such","  signals now defers to one that matched an actual error. A genuine artifact or cache","  failure is unaffected: it trips a terminal signal (\"Failed to CreateArtifact\",","  \"Unable to download artifact\", \"Cache service responded with 500\").","- The classifier no longer reads a command that merely *ran* as the failure. Three","  bugs of the same shape, all found by running `ci explain` over real failing runs","  from public repositories rather than over the fixture zoo:","  - `\\btsc\\b` matched the x86 **time stamp counter** in the `flags :` line of","    `/proc/cpuinfo`, which perf-sensitive projects dump into their log preamble.","    A real rust-lang/rust build failure came back as `typescript_typecheck` on the","    strength of a CPU feature name. `tsc` now only counts in command position","    (`pnpm tsc`, `\u003e tsc --noEmit`, `npx tsc`, `tsc -p …`) or before a flag/verb.","  - `docker build` / `docker buildx build` / `docker compose` appear in every job","    that builds a container as a setup step, and `cargo test` / `clippy` appear in","    the command line of every Rust CI job, passing or not. A rule matching *only*","    such signals now defers to a rule that matched an actual error, reusing the","    deferral already in place for ambiguous network signals. They still count","    toward confidence when a real error sits beside them, so a genuine docker or","    clippy failure is unchanged.","  - Because scoring is by matched-pattern count, one bogus signal was enough to tie","    the rule that matched the real error and beat it on declaration order alone.","    The zoo missed all of this: its fixtures are clean, and a real log is not — the","    same `error[E0277]` that a fixture classifies correctly was misread in the wild","    because the job also happened to run `docker buildx build`.","  No fixture changes classification or confidence (221 fixtures, top-1 1.0).","","### Added","","- `patchrail schema ci-classes` now serves a published schema for","  `ci classes --format json`, and the suite validates real output against it.","  It was the one JSON command with no schema, no conformance test and no","  cookbook entry — which is why 0.4.0 could move it from","  `patchrail.ci_classes.v1` to `.v2` in a minor bump without anything going","  red, and why the break reached consumers (this project's own GitHub Action","  among them) silently. Changing the contract now means shipping the schema","  that describes it: `test_schema_conformance.py` compares the `schema_version`","  the CLI emits against the `const` in the schema a user can fetch, so the two","  cannot drift apart again. The schema also encodes the v2 rule itself —","  `unknown` is valid under `fallback` and rejected inside `classes` — so","  putting the sentinel back into the denominator fails validation.","- `docs/json-cookbook.md` documents the `ci classes` payload with a coverage","  recipe (which supported classes has a log corpus never exercised?), and its","  sample output is pinned to the code by `test_readme_claims.py` in both","  directions, like the README's counts.","","## 0.4.0 - 2026-07-14","","Minor bump rather than a patch: `ci classes --format json` changes its contract.","`schema_version` is now `patchrail.ci_classes.v2` and `unknown` left `classes`","and `count` (see Fixed). Scripts pinned to the v1 shape need a one-line update.","","### Fixed","","- `patchrail ci classes` no longer counts `unknown` as a supported failure","  class. It reported \"41 supported failure classes\" and listed `unknown` — with","  a reproduction command — alongside the 40 real ones, contradicting the README,","  the docs and the fixture benchmark, all of which say 40. `unknown` is what","  `ci explain` returns when *no* rule matches, so a coverage script following the","  README (`ci classes --format json`) was dividing by a denominator containing an","  entry it could never cover. The sentinel is still reported, under a new","  `fallback` key, and named in the text and markdown output; it is just out of","  `classes` and `count`. JSON consumers: `schema_version` is now","  `patchrail.ci_classes.v2`.","- README: the redaction bullet advertised 23 secret-redaction patterns; the","  shipped table has 24. The class, fixture and redaction counts the README","  advertises are now derived from the code by `tests/test_readme_claims.py`, so","  they fail the build instead of going stale (the fixture count was already","  pinned by tests, and it was the only one of the three that had stayed correct).","","### Changed","","- `patchrail ci explain`/`classify` now print a first-use hint when the log","  input is empty or whitespace-only. The common cause is the README one-liner","  `gh run view --log-failed | patchrail ci explain` pointed at a run whose logs","  GitHub already expired (or a run that has not failed), which pipes in nothing.","  The error keeps its exit code `2` and clean stdout; it just adds a line","  telling the user to point it at a *recent* failed run instead of leaving them","  guessing. Non-empty input is completely unaffected.","","## 0.3.1 - 2026-07-11","","### Added","","- `patchrail ci explain`/`classify` now turn an `unknown` result into a","  contribution on-ramp: the text and markdown reports append one line pointing","  the maintainer at the `ci_failure_fixture` issue template","  (`.../issues/new?template=ci_failure_fixture.md`) so an unrecognized log","  becomes a fixture request instead of a dead-end. The classifier's behavior","  and JSON output are unchanged — the pointer is presentation-only and appears","  solely when `failure_class == \"unknown\"`.","- `patchrail -V` is now a short alias for `--version`. Both print","  `patchrail \u003cversion\u003e` and exit `0`, matching the conventional single-letter","  flag most CLIs expose (handy in bug reports and CI logs).","- New `tests/test_schema_conformance.py` validates real CLI output against","  `src/patchrail/schemas/*.v1.schema.json` with `jsonschema` (dev-only","  dependency; the installed package still ships with zero runtime","  dependencies). Previously `_load_schema()` only read schema files as text","  to print them via `patchrail ci schema`; nothing checked that a payload","  builder's output still matched its schema. Covers `ci-result` (every","  fixture in `examples/ci-triage/`, 221 cases), `ci-benchmark`, and","  `ci-fixture-check`.","- `mypy --strict` now runs on `src/patchrail/ci/classify.py` (the classifier","  engine) as a dev dependency and a CI step, alongside `ruff check`/`ruff","  format --check`. The module already passed strict type checking with no","  changes required; this locks that in against regressions. See","  `[tool.mypy]` in `pyproject.toml`.","- New sanitized `github-actions-cmake-gcc-compile-error` fixture covers a real","  CMake + g++ undeclared-identifier link failure for `cpp_build_failure`, which","  previously had a classifier rule but no fixture in the benchmark zoo despite","  the README advertising C++ support. Bringing the benchmark zoo to 220 cases.","- `java_build_failure` now also recognises kotlinc's own diagnostic format","  (`e: File.kt: (line, col): ...`), `Unresolved reference:`, and Kotlin Gradle","  task failures (`:compileDebugKotlin FAILED`). A maintainer pasting only the","  kotlinc excerpt of a Kotlin/Android CI failure — without the Gradle","  `Execution failed for task` / `BUILD FAILED` banner further down the log —","  previously fell through to `unknown` at 0.15 confidence. New sanitized","  `github-actions-kotlin-compile-excerpt-no-banner` fixture guards this,","  bringing the benchmark zoo to 221 cases.","","### Fixed","","- `patchrail ci explain`/`classify` now normalize the GitHub Actions log line","  prefix before classifying, so the common one-liner","  `gh run view \u003crun-id\u003e --log-failed --repo \u003cowner/repo\u003e | patchrail ci explain`","  classifies identically to a saved raw log. `gh` prefixes every line with","  `\u003cjob\u003e\\t\u003cstep\u003e\\t\u003ctimestamp\u003e` (and a UTF-8 BOM on the first line), which shifted","  real content off the start of the line and silently defeated the classifier's","  line-anchored (`^`) patterns — dropping confidence (e.g. `go_lint` and","  `node_test_failure` fell from `0.95` to `0.89` on sparse logs). The raw","  Actions log-download form (`\u003ctimestamp\u003e \u003cline\u003e`) is normalized too. Regression","  cases in `tests/test_ci_classify_expansion.py` pin gh-prefixed == raw.","","### Changed","","- Extracted the entire `funded-issues` subcommand group (20 argparse handlers,","  ~50 markdown/text/CSV/JSONL renderers, and the argparse wiring for all 20","  sub-subcommands — 3853 of `cli.py`'s 10368 lines) into a new","  `src/patchrail/cli_funded.py` module, registered from `_build_parser()` via","  `cli_funded.register(subparsers)`. No behavior change: same commands, same","  flags, same output. `cli.py` drops from 10368 to ~5650 lines. If you import","  `patchrail.cli._normalize_recheck_observation` or similar funded-issues","  internals directly (rather than going through the public CLI), import from","  `patchrail.cli_funded` instead.","","## 0.3.0 - 2026-07-09","","### Fixed","","- Deterministic Go test failures are no longer misread as","  `network_transient_failure` when their logs contain incidental","  network-shaped noise (`dial tcp`, `connection refused`, `context deadline","  exceeded`, `i/o timeout`). The classifier now defers a broad transient-network","  match built *entirely* from these ambiguous signals to the concrete failure","  when one also matched, so a real bug isn't mislabeled \"just retry\". Genuine","  outages still classify as transient because they trip a terminal signal (DNS","  resolution, rate limit, gateway error, TLS handshake, or a git remote hang-up)","  outside the ambiguous set. `go_test_failure` also now recognises the canonical","  `--- FAIL:` marker. New `go-integration-test-network-noise` fixture guards this,","  bringing the benchmark zoo to 208 cases.","","### Added","","- `patchrail --version` now prints the installed version (e.g. `patchrail 0.3.0`)","  and exits, so a maintainer can confirm which release they are running without","  invoking a subcommand.","- `java_build_failure` now also recognises **sbt** (Scala on the JVM). sbt prints","  none of the Maven/Gradle banners the rule keyed on, so a genuine","  `(project / Test / compileIncremental) Compilation failed` — or an","  `sbt.TestsFailedException` — previously fell through to `unknown`. New signals","  cover the sbt session banner, incremental-compile failure, Scala","  `not found: value`/`not found: type` errors, and the sbt test-failure","  exception; the reproduction command now suggests `sbt test`. New sanitized","  `github-actions-sbt-scala-compile` fixture (modelled on a real","  `scalatest/scalatest` GitHub Actions run) guards this, bringing the benchmark","  zoo to 209 cases.","- New sanitized `ruby-rspec-parallel-failure` fixture captures a real","  `rubocop/rubocop` RSpec failure tail (parallel/turbo_tests summary with","  `pending` before `failures`), bringing the benchmark zoo to 207 cases.","- New `xcode_build_failure` class classifies Apple-platform build and test","  failures from `xcodebuild`, `swift build`/`swift test`, and Swift Package","  Manager — Swift compile errors, missing modules (`error: no such module`),","  unresolved package dependencies, and XCTest failures (`** BUILD FAILED **`,","  `** TEST FAILED **`, `The following build commands failed:`). Backed by three","  sanitized fixtures in `examples/ci-triage/`, bringing the benchmark zoo to 169","  cases and the classifier to 40 failure classes.","- New `docs_build_failure` class classifies documentation-site build failures","  from Sphinx (`sphinx-build -W` warnings-as-errors, missing toctree entries),","  MkDocs (`mkdocs build --strict` broken links), and Docusaurus (`docusaurus","  build` broken links). Backed by three sanitized fixtures in","  `examples/ci-triage/`, bringing the benchmark zoo to 166 cases.","- `patchrail ci classes` lists every supported failure class with its likely","  subsystem and reproduction command (plus the `unknown` fallback), in stable","  order. Supports `--format text|json|markdown` and `--out`, so the set of","  classes the classifier can diagnose is discoverable from the CLI instead of","  only in the source. Closes #150.","","### Fixed","","- Real RSpec failures now classify as `ruby_bundle_failure` instead of","  `unknown`. RSpec prints its rerun list as `rspec ./path/to/thing_spec.rb[…]`","  and its summary as `N examples, [K pending, ]M failures` (rspec, parallel and","  turbo_tests) — neither of which the old `rspec .*failures?` pattern matched,","  so a pasted spec-failure tail without bundler setup lines fell through to","  `unknown`. Two shape-matching patterns were added to the rule. Surfaced by","  dogfooding a real `rubocop/rubocop` CI run.","- Python CI logs no longer misclassify as `python_dependency_resolution` just","  because they run `python -m pip install`. That bare command line was a","  detection pattern, but it appears in almost every Python CI job regardless of","  what actually failed, so any failing Python job with no stronger signal was","  reported as a dependency-resolution conflict with the misleading \"pin or relax","  the conflicting dependency range\" advice. Dogfooded against a real","  `pandas-dev/pandas` 32-bit CI run whose `pip install` failed at","  `metadata-generation-failed` (a package build error, `Rust not found`) — it was","  reported as `python_dependency_resolution` (0.53). The boilerplate pattern is","  dropped, so a build/metadata failure with no genuine resolution signal now","  stays honest (`unknown`) instead. To keep recall on real conflicts, two","  genuine pip signals were added: pip's actual Requires-Python wording","  (`requires a different Python:`) and its no-distribution `(from versions: …)`","  line; the three synthetic no-matching-distribution fixtures were updated to","  include the real `(from versions: …)` output pip prints. Benchmark stays at","  206/206 top-1 with all confidence floors met; the bundled dependency-failure","  demo now reports 0.89 (three genuine resolution signals) instead of 0.95.","  Regression covered in `tests/`.","- `patchrail ci explain`/`classify` no longer hangs on large CI logs. The","  `github_actions_workflow` rule paired two unanchored lookaheads","  (`(?=[\\s\\S]*.github/workflows/…)(?=[\\s\\S]*Invalid workflow file…)`); under","  `re.search` that compound is retried at every start position, so a log that","  mentions `.github/workflows/*.yml` (every `actions/checkout` step does) but not","  a workflow-error phrase drove the matcher into O(n²) backtracking and pegged a","  core at 100% for minutes. Dogfooded against a real `cli/cli` Go CI run","  (~200 KB) that never returned. The lookahead is now anchored with `\\A` so it is","  evaluated once, in linear time; the \"workflow path AND error phrase present\"","  signal is unchanged. Regression covered in `tests/`.","- Rust CI failures no longer misclassify as `node_dependency_install`,","  `dotnet_build_failure`, or `java_build_failure` because of generic boilerplate.","  The `Swatinem/rust-cache` action prints `Lockfiles considered:` (which matched","  the old bare `lockfile` node signal) and cargo prints `build failed, waiting","  for other jobs to finish` (which matched the case-insensitive `Build FAILED` /","  `BUILD FAILED` banners). The node lockfile signal now requires a whole-word","  `lockfile`, and the .NET/Gradle banners are matched case-sensitively so they","  fire only on the tool's actual `Build FAILED` / `BUILD FAILED` output. A real","  `tokio-rs/tokio` rustdoc failure (`error[E0433]`) now classifies as","  `rust_test_failure`. Regression covered in `tests/`.","- Sharper reproduce commands for three failure classes surfaced by `patchrail ci","  classes` / `ci explain`. `node_script_missing` no longer suggests `npm run","  build` (which just re-triggers the \"missing script\" error) and instead runs","  `npm run` to list the scripts `package.json` actually defines, so you can","  compare against the one your workflow calls. `security_scan_failure` names the","  concrete scanners to rerun locally (`npm audit`, `pip-audit`, `cargo audit`,","  `trivy fs .`, `bandit -r .`, `semgrep --config auto`) instead of the generic","  \"rerun the failing security scan locally\". `github_actions_workflow` points at","  `actionlint .github/workflows/`, which validates workflow syntax and action","  refs locally, rather than only printing the YAML back with `gh workflow view`.","- Real GitHub Actions logs no longer misclassify as `git_checkout_failure` when","  checkout actually succeeded. The rule dropped three boilerplate signals that","  appear in almost every Actions log regardless of outcome — the `actions/checkout`","  setup step, the `git submodule foreach` post-job cleanup line, and a bare","  `git-lfs` mention — keeping only genuine checkout/clone/submodule/LFS *failure*","  markers (`fatal: ...`, `Failed to fetch submodule`, `smudge filter lfs failed`,","  `error downloading object`, …). Dogfooded against a real `pallets/flask` CI run","  whose pytest jobs failed on a conftest `SyntaxError` but were reported as a git","  checkout problem.","- `python_test_failure` now also recognizes pytest collection failures","  (`ImportError while loading conftest ...`, `N errors during collection`), so a","  broken `conftest.py` or import-time error surfaces as a test failure with the","  `python -m pytest -q` reproduce line instead of falling through to a weaker or","  wrong class.","- `patchrail ci explain` and `ci classify` now fail clearly on empty or","  whitespace-only input (from `--log` or stdin) instead of silently reporting","  `failure_class: unknown` with confidence `0.15` and exit code `0`. They print","  `log input is empty` to stderr, exit with code `2`, and write nothing to","  `--out`, so a bad shell redirect is no longer mistaken for an unclassifiable","  log. Closes #151.","- Added `node_script_missing` to the published `ci-result` schema enum; the","  classifier could already emit it, so a valid classification previously failed","  schema validation for downstream consumers. A new test guards that every rule","  class is declared in the schema enum.","","## 0.2.0 - 2026-07-07","","### Removed","","- Removed the commercial `Guide:` link that `ci explain` appended to text and","  Markdown reports, and the matching guide URL outputs from the GitHub Action.","  Reports now end after the classification; per-class remediation write-ups","  live in-repo under `docs/fix/`.","- Removed commercial product links and campaign-tagged URLs from the README,","  docs, and the PyPI project URL list.","- Removed the distribution and web-metrics tooling (`ci share-links` and the","  web metrics commands and store). PatchRail no longer ships link-tracking or","  distribution helpers.","","### Changed","","- `funded-issues` is now explicitly labeled experimental. Discovery commands","  default to safe-only filtering, and risky entries require an explicit","  `--include-risky` flag.","- Rewrote the README around the open-source CI triage workflow: quickstart","  with real classifier output, honest feature table, local-first safety","  section, and the fixture contribution path.","","### Added","","- Added `node_script_missing` CI classification so npm/pnpm/yarn jobs that","  call a missing package script are separated from dependency-install failures","  and routed to a workflow/script repair path.","- Added a permanent source-level blocklist to the funded-issues tracker:","  owners manually verified as fake-bounty sources are dropped at the","  `merge_into_store` choke point (counted as `blocked` in the merge summary)","  and `purge_blocklisted_entries` removes any legacy entries; `track` runs the","  purge on every merge so existing stores self-heal.","- Added `funded-issues import-algora-board`, an offline parser for a locally","  saved Algora organization bounty-board page. It extracts the funder-stated","  USD amount, GitHub issue reference, posting age, and declared claim count","  per bounty, and can merge the scored records into a tracker store. No","  network access is performed.","- Added read-only competition and payout-vs-effort scoring signals plus the","  `funded-issues competition` and `funded-issues payout-effort` batch","  commands, all derived from public metadata observations with no claims,","  comments, or maintainer contact.","- Added an offline owner-level `source_noise` heuristic and","  `funded-issues apply-recheck`, a local-file-only command that transitions","  tracker entries to closed / stale / active from recheck observations.","- Added .NET/NuGet/C# and xUnit fixture coverage for `dotnet restore`,","  `dotnet build`, and `dotnet test` failure modes, growing the public CI","  fixture zoo to 153 cases.","","## 0.1.1 - 2026-06-12","","- `ci explain` now ends text and Markdown reports with a `Guide:` link to the","  matching getpatchrail.com `/fix` remediation page; unknown or unpublished","  failure classes fall back to the `/fix` index without a network call.","- Added `funded-issues fresh`, a local read-only radar over the tracker store","  that surfaces recently posted or recently labeled funded issues for fast","  solver-side triage.","- Added `pre_commit_hook_failure` CI classification so pre-commit hook output is","  recognized directly while the CLI still avoids linking to a missing `/fix`","  page until that guide exists.","","## 0.1.0 - 2026-06-02","","- Initial public CI Janitor snapshot.","- Added `patchrail ci explain` and `patchrail ci classify`.","- Added local Markdown, JSON, and text reports.","- Added Apache-2.0 license and safety/ethics documentation.","- Added fixture-backed tests, local benchmark command, and GitHub Actions CI.","- Expanded the initial CI fixture zoo to 101 sanitized synthetic examples across","  Python, Node, TypeScript, Go, Rust, and GitHub Actions failure modes.","- Added a read-only GitHub Actions triage artifact workflow.","- Added the experimental local Agent Control Plane queue with SQLite-backed","  work items, approval states, audit export, CI result import, and proposal","  records.","- Added the experimental read-only `funded-issues` CLI over local metadata,","  with safe-only filtering and explicit anti-abuse blocked actions.","- Added permission-only adopter reporting and a public metrics tracker for","  pilot outcomes, adoption signals, and open-source program evidence gaps.","- Added release-prep evidence docs, package smoke checks, and manual publish","  gates. Release tags, PyPI publishing, GitHub Releases, and public","  announcements remain maintainer actions."],"stylingDirectives":[[[0,11,"pl-mh"],[2,11,"pl-en"]],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"],[2,4,"pl-s"],[26,27,"pl-s"],[32,33,"pl-s"],[76,78,"pl-s"]],[[10,11,"pl-s"],[11,21,"pl-c1"],[21,22,"pl-s"]],[],[],[[2,3,"pl-v"],[4,5,"pl-s"],[5,18,"pl-c1"],[18,19,"pl-s"],[46,47,"pl-s"],[47,53,"pl-c1"],[53,54,"pl-s"]],[[45,46,"pl-s"],[46,56,"pl-c1"],[56,57,"pl-s"],[70,71,"pl-s"],[77,78,"pl-s"]],[[4,5,"pl-s"],[5,9,"pl-c1"],[9,10,"pl-s"]],[[10,11,"pl-s"],[11,32,"pl-c1"],[32,33,"pl-s"],[61,62,"pl-s"],[62,73,"pl-c1"],[73,74,"pl-s"]],[[2,3,"pl-v"],[55,56,"pl-s"],[56,79,"pl-c1"],[79,80,"pl-s"]],[[4,5,"pl-s"],[5,9,"pl-c1"],[9,10,"pl-s"]],[[33,34,"pl-s"],[34,51,"pl-c1"],[51,52,"pl-s"]],[],[[32,33,"pl-s"],[37,38,"pl-s"]],[[12,13,"pl-s"],[13,19,"pl-c1"],[19,20,"pl-s"],[51,52,"pl-s"],[52,57,"pl-c1"],[57,58,"pl-s"]],[],[],[],[[45,46,"pl-s"],[46,70,"pl-c1"],[70,71,"pl-s"]],[],[],[[0,1,"pl-v"],[2,4,"pl-s"],[4,5,"pl-s"],[5,24,"pl-c1"],[24,25,"pl-s"],[62,64,"pl-s"]],[[2,3,"pl-s"],[8,9,"pl-s"],[24,25,"pl-s"],[25,36,"pl-c1"],[36,37,"pl-s"],[49,50,"pl-s"],[50,56,"pl-c1"],[56,57,"pl-s"]],[[2,3,"pl-s"],[3,46,"pl-c1"],[46,47,"pl-s"],[49,50,"pl-s"],[50,73,"pl-c1"],[73,74,"pl-s"]],[[20,21,"pl-s"],[21,50,"pl-c1"],[50,51,"pl-s"]],[[18,19,"pl-s"],[19,21,"pl-c1"],[21,22,"pl-s"]],[[83,84,"pl-s"],[84,85,"pl-c1"],[85,86,"pl-s"]],[[14,15,"pl-s"],[15,23,"pl-c1"],[23,24,"pl-s"]],[],[[0,1,"pl-v"],[2,4,"pl-s"],[49,51,"pl-s"]],[[48,49,"pl-s"],[49,60,"pl-c1"],[60,61,"pl-s"]],[[2,3,"pl-s"],[3,26,"pl-c1"],[26,27,"pl-s"]],[],[[2,3,"pl-s"],[3,5,"pl-c1"],[5,6,"pl-s"],[31,32,"pl-s"],[38,39,"pl-s"],[59,60,"pl-s"],[60,88,"pl-c1"],[88,89,"pl-s"]],[[7,8,"pl-s"],[8,19,"pl-c1"],[19,20,"pl-s"]],[[63,64,"pl-s"],[64,89,"pl-c1"],[89,90,"pl-s"]],[[55,56,"pl-s"],[56,62,"pl-c1"],[62,63,"pl-s"]],[[18,19,"pl-s"],[19,23,"pl-c1"],[23,24,"pl-s"],[41,42,"pl-s"],[42,44,"pl-c1"],[44,45,"pl-s"]],[[43,44,"pl-s"],[44,56,"pl-c1"],[56,57,"pl-s"],[59,60,"pl-s"],[60,67,"pl-c1"],[67,68,"pl-s"]],[],[[0,1,"pl-v"],[2,4,"pl-s"],[65,67,"pl-s"],[68,69,"pl-s"],[69,92,"pl-c1"],[92,93,"pl-s"]],[],[[13,14,"pl-s"],[21,22,"pl-s"]],[],[[17,18,"pl-s"],[18,31,"pl-c1"],[31,32,"pl-s"]],[],[],[],[],[[0,1,"pl-v"],[55,56,"pl-s"],[59,60,"pl-s"]],[[47,48,"pl-s"],[48,58,"pl-c1"],[58,59,"pl-s"]],[],[[2,3,"pl-v"],[4,5,"pl-s"],[5,12,"pl-c1"],[12,13,"pl-s"],[30,32,"pl-s"],[50,52,"pl-s"],[60,61,"pl-s"],[61,68,"pl-c1"],[68,69,"pl-s"]],[[4,5,"pl-s"],[5,18,"pl-c1"],[18,19,"pl-s"]],[[53,54,"pl-s"],[54,74,"pl-c1"],[74,75,"pl-s"]],[[36,37,"pl-s"],[37,40,"pl-c1"],[40,41,"pl-s"]],[[5,6,"pl-s"],[6,14,"pl-c1"],[14,15,"pl-s"],[17,18,"pl-s"],[18,32,"pl-c1"],[32,33,"pl-s"],[35,36,"pl-s"],[36,43,"pl-c1"],[43,44,"pl-s"],[46,47,"pl-s"],[47,55,"pl-c1"],[55,56,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[5,17,"pl-c1"],[17,18,"pl-s"],[21,22,"pl-s"],[22,41,"pl-c1"],[41,42,"pl-s"],[45,46,"pl-s"],[46,60,"pl-c1"],[60,61,"pl-s"]],[[49,50,"pl-s"],[50,60,"pl-c1"],[60,61,"pl-s"],[64,65,"pl-s"],[65,71,"pl-c1"],[71,72,"pl-s"]],[[75,76,"pl-s"],[80,81,"pl-s"]],[],[],[],[],[[2,3,"pl-v"]],[],[],[[9,10,"pl-s"],[10,22,"pl-c1"],[22,23,"pl-s"]],[[41,42,"pl-s"],[42,61,"pl-c1"],[61,62,"pl-s"]],[],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,30,"pl-c1"],[30,31,"pl-s"]],[[2,3,"pl-s"],[3,27,"pl-c1"],[27,28,"pl-s"]],[],[],[[2,3,"pl-s"],[3,26,"pl-c1"],[26,27,"pl-s"],[31,32,"pl-s"],[32,35,"pl-c1"],[35,36,"pl-s"]],[],[],[[21,22,"pl-s"],[22,48,"pl-c1"],[48,49,"pl-s"],[63,64,"pl-s"],[64,78,"pl-c1"],[78,79,"pl-s"]],[[28,29,"pl-s"],[29,34,"pl-c1"],[34,35,"pl-s"]],[],[[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[27,28,"pl-s"],[28,36,"pl-c1"],[36,37,"pl-s"],[58,59,"pl-s"],[59,66,"pl-c1"],[66,67,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,24,"pl-c1"],[24,25,"pl-s"],[40,41,"pl-s"],[41,51,"pl-c1"],[51,52,"pl-s"]],[],[[41,42,"pl-s"],[42,63,"pl-c1"],[63,64,"pl-s"]],[],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[[32,33,"pl-s"],[33,57,"pl-c1"],[57,58,"pl-s"]],[[0,1,"pl-s"],[1,15,"pl-c1"],[15,16,"pl-s"],[24,25,"pl-s"],[25,48,"pl-c1"],[48,49,"pl-s"],[54,55,"pl-s"],[55,62,"pl-c1"],[62,63,"pl-s"],[69,70,"pl-s"],[70,77,"pl-c1"],[77,78,"pl-s"]],[[4,5,"pl-s"],[5,10,"pl-c1"],[10,11,"pl-s"]],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[42,43,"pl-s"],[43,50,"pl-c1"],[50,51,"pl-s"]],[[63,64,"pl-s"],[64,71,"pl-c1"],[71,72,"pl-s"]],[],[[59,60,"pl-s"],[60,67,"pl-c1"],[67,68,"pl-s"]],[[2,3,"pl-s"],[3,13,"pl-c1"],[13,14,"pl-s"],[28,29,"pl-s"],[31,32,"pl-s"]],[[10,11,"pl-s"],[11,35,"pl-c1"],[35,36,"pl-s"]],[],[[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"]],[[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[16,17,"pl-s"],[17,22,"pl-c1"],[22,23,"pl-s"],[41,42,"pl-s"],[42,56,"pl-c1"],[56,57,"pl-s"]],[[2,3,"pl-s"],[3,26,"pl-c1"],[26,27,"pl-s"]],[[0,1,"pl-v"]],[],[[46,47,"pl-s"],[47,74,"pl-c1"],[74,75,"pl-s"]],[],[],[],[[0,11,"pl-mh"],[4,11,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[25,26,"pl-s"],[26,34,"pl-c1"],[34,35,"pl-s"]],[],[[2,3,"pl-s"],[3,50,"pl-c1"],[50,51,"pl-s"]],[],[[32,33,"pl-s"],[33,34,"pl-c1"],[34,35,"pl-s"]],[[36,37,"pl-s"],[43,44,"pl-s"]],[],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[25,26,"pl-s"],[26,34,"pl-c1"],[34,35,"pl-s"],[48,49,"pl-s"],[49,56,"pl-c1"],[56,57,"pl-s"]],[],[[24,25,"pl-s"],[25,43,"pl-c1"],[43,44,"pl-s"]],[[3,4,"pl-s"],[4,49,"pl-c1"],[49,50,"pl-s"]],[],[],[[14,15,"pl-s"],[15,41,"pl-c1"],[41,42,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"],[42,43,"pl-s"],[43,52,"pl-c1"],[52,53,"pl-s"]],[[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[33,34,"pl-s"],[34,35,"pl-c1"],[35,36,"pl-s"]],[],[[0,1,"pl-v"],[6,7,"pl-s"],[7,39,"pl-c1"],[39,40,"pl-s"]],[[2,3,"pl-s"],[3,41,"pl-c1"],[41,42,"pl-s"],[48,49,"pl-s"],[49,59,"pl-c1"],[59,60,"pl-s"]],[],[[28,29,"pl-s"],[29,43,"pl-c1"],[43,44,"pl-s"]],[[20,21,"pl-s"],[21,40,"pl-c1"],[40,41,"pl-s"]],[[52,53,"pl-s"],[53,62,"pl-c1"],[62,63,"pl-s"]],[[13,14,"pl-s"],[14,33,"pl-c1"],[33,34,"pl-s"],[48,49,"pl-s"],[49,61,"pl-c1"],[61,62,"pl-s"]],[[2,3,"pl-s"],[3,19,"pl-c1"],[19,20,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"],[30,31,"pl-s"],[31,59,"pl-c1"],[59,60,"pl-s"]],[[55,56,"pl-s"],[56,66,"pl-c1"],[66,67,"pl-s"]],[],[],[[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"],[19,20,"pl-s"],[20,34,"pl-c1"],[34,35,"pl-s"]],[[0,1,"pl-v"],[16,17,"pl-s"],[17,55,"pl-c1"],[55,56,"pl-s"]],[[53,54,"pl-s"],[54,71,"pl-c1"],[71,72,"pl-s"]],[],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"]],[[3,4,"pl-s"],[4,32,"pl-c1"],[32,33,"pl-s"],[36,37,"pl-s"],[37,58,"pl-c1"],[58,59,"pl-s"]],[[17,18,"pl-s"],[18,44,"pl-c1"],[44,45,"pl-s"]],[],[[2,3,"pl-s"],[3,28,"pl-c1"],[28,29,"pl-s"],[32,33,"pl-s"],[33,45,"pl-c1"],[45,46,"pl-s"]],[[29,30,"pl-s"],[30,37,"pl-c1"],[37,38,"pl-s"]],[[2,3,"pl-s"],[3,50,"pl-c1"],[50,51,"pl-s"]],[],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[25,26,"pl-s"],[26,34,"pl-c1"],[34,35,"pl-s"]],[],[[2,3,"pl-s"],[3,79,"pl-c1"],[79,80,"pl-s"]],[[45,46,"pl-s"],[46,48,"pl-c1"],[48,49,"pl-s"]],[[2,3,"pl-s"],[3,29,"pl-c1"],[29,30,"pl-s"]],[],[[17,18,"pl-s"],[18,19,"pl-c1"],[19,20,"pl-s"],[59,60,"pl-s"],[60,67,"pl-c1"],[67,68,"pl-s"]],[[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[32,33,"pl-s"],[33,37,"pl-c1"],[37,38,"pl-s"],[42,43,"pl-s"],[43,47,"pl-c1"],[47,48,"pl-s"]],[[29,30,"pl-s"],[30,48,"pl-c1"],[48,49,"pl-s"]],[[11,12,"pl-s"],[12,47,"pl-c1"],[47,48,"pl-s"]],[],[[0,11,"pl-mh"],[4,11,"pl-en"]],[],[[0,1,"pl-v"],[23,24,"pl-s"],[24,37,"pl-c1"],[37,38,"pl-s"]],[[2,3,"pl-s"]],[[28,29,"pl-s"],[29,35,"pl-c1"],[35,36,"pl-s"]],[[2,3,"pl-s"],[3,30,"pl-c1"],[30,31,"pl-s"],[56,57,"pl-s"],[57,72,"pl-c1"],[72,73,"pl-s"]],[[2,3,"pl-s"],[3,34,"pl-c1"],[34,35,"pl-s"]],[[22,23,"pl-s"],[23,29,"pl-c1"],[29,30,"pl-s"],[51,52,"pl-s"]],[[2,3,"pl-s"],[3,47,"pl-c1"],[47,48,"pl-s"]],[],[[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"]],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"]],[[2,3,"pl-s"],[3,28,"pl-c1"],[28,29,"pl-s"]],[[24,25,"pl-s"],[25,33,"pl-c1"],[33,34,"pl-s"],[36,37,"pl-s"],[37,55,"pl-c1"],[55,56,"pl-s"]],[[10,11,"pl-s"],[11,13,"pl-c1"],[13,14,"pl-s"]],[[14,15,"pl-s"],[23,24,"pl-s"]],[],[],[],[[29,30,"pl-s"],[30,45,"pl-c1"],[45,46,"pl-s"]],[[2,3,"pl-s"],[3,12,"pl-c1"],[12,13,"pl-s"],[26,27,"pl-s"],[27,60,"pl-c1"],[60,61,"pl-s"]],[],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"],[63,64,"pl-s"],[64,79,"pl-c1"],[79,80,"pl-s"]],[],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"],[43,45,"pl-s"],[48,50,"pl-s"]],[],[[2,3,"pl-s"],[3,59,"pl-c1"],[59,60,"pl-s"]],[[2,3,"pl-s"],[3,27,"pl-c1"],[27,28,"pl-s"],[58,59,"pl-s"],[59,66,"pl-c1"],[66,67,"pl-s"]],[],[[2,3,"pl-s"],[3,19,"pl-c1"],[19,20,"pl-s"],[21,22,"pl-s"],[22,37,"pl-c1"],[37,38,"pl-s"]],[[51,52,"pl-s"],[52,60,"pl-c1"],[60,61,"pl-s"]],[[2,3,"pl-s"],[3,35,"pl-c1"],[35,36,"pl-s"]],[[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"]],[],[[0,1,"pl-v"],[16,17,"pl-s"],[17,44,"pl-c1"],[44,45,"pl-s"]],[[2,3,"pl-s"],[3,18,"pl-c1"],[18,19,"pl-s"]],[[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[19,20,"pl-s"],[20,28,"pl-c1"],[28,29,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,26,"pl-c1"],[26,27,"pl-s"]],[[16,17,"pl-s"],[17,27,"pl-c1"],[27,28,"pl-s"],[30,31,"pl-s"],[31,42,"pl-c1"],[42,43,"pl-s"],[44,45,"pl-s"],[45,55,"pl-c1"],[55,56,"pl-s"]],[[51,52,"pl-s"],[52,73,"pl-c1"],[73,74,"pl-s"]],[[56,57,"pl-s"],[57,75,"pl-c1"],[75,76,"pl-s"]],[[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[23,24,"pl-s"],[24,60,"pl-c1"],[60,61,"pl-s"]],[[24,25,"pl-s"],[25,44,"pl-c1"],[44,45,"pl-s"]],[],[[0,1,"pl-v"],[6,7,"pl-s"],[7,25,"pl-c1"],[25,26,"pl-s"]],[[15,16,"pl-s"],[16,31,"pl-c1"],[31,32,"pl-s"]],[[10,11,"pl-s"],[11,32,"pl-c1"],[32,33,"pl-s"]],[],[[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"]],[[47,48,"pl-s"],[48,55,"pl-c1"],[55,56,"pl-s"]],[[18,19,"pl-s"],[19,46,"pl-c1"],[46,47,"pl-s"],[52,53,"pl-s"],[53,58,"pl-c1"],[58,59,"pl-s"]],[],[[29,33,"pl-s"],[30,33,"pl-corl"]],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"],[38,39,"pl-s"],[39,58,"pl-c1"],[58,59,"pl-s"]],[[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[44,45,"pl-s"],[45,77,"pl-c1"],[77,78,"pl-s"]],[[21,22,"pl-s"],[22,57,"pl-c1"],[57,58,"pl-s"]],[[42,43,"pl-s"],[43,60,"pl-c1"],[60,61,"pl-s"]],[],[[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"]],[[20,21,"pl-s"],[21,36,"pl-c1"],[36,37,"pl-s"]],[[0,1,"pl-v"],[42,43,"pl-s"],[43,71,"pl-c1"],[71,72,"pl-s"]],[[19,20,"pl-s"],[20,41,"pl-c1"],[41,42,"pl-s"]],[],[],[],[],[[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[42,43,"pl-s"],[43,54,"pl-c1"],[54,55,"pl-s"]],[[2,3,"pl-s"],[3,29,"pl-c1"],[29,30,"pl-s"],[55,56,"pl-s"],[56,70,"pl-c1"],[70,71,"pl-s"]],[[14,15,"pl-s"],[15,43,"pl-c1"],[43,44,"pl-s"]],[],[[16,17,"pl-s"],[17,24,"pl-c1"],[24,25,"pl-s"]],[],[[3,4,"pl-s"],[4,32,"pl-c1"],[32,33,"pl-s"],[59,60,"pl-s"],[60,78,"pl-c1"],[78,79,"pl-s"]],[],[[19,20,"pl-s"],[20,38,"pl-c1"],[38,39,"pl-s"]],[],[],[[24,25,"pl-s"],[25,31,"pl-c1"],[31,32,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[25,26,"pl-s"],[26,34,"pl-c1"],[34,35,"pl-s"]],[[2,3,"pl-s"],[3,26,"pl-c1"],[26,27,"pl-s"]],[[3,4,"pl-s"],[4,67,"pl-c1"],[67,68,"pl-s"]],[[2,3,"pl-s"],[3,12,"pl-c1"],[12,13,"pl-s"]],[[11,12,"pl-s"],[12,35,"pl-c1"],[35,36,"pl-s"],[44,45,"pl-s"],[45,61,"pl-c1"],[61,62,"pl-s"]],[],[[53,54,"pl-s"],[54,61,"pl-c1"],[61,62,"pl-s"]],[[3,4,"pl-s"],[68,69,"pl-s"],[69,71,"pl-c1"],[71,72,"pl-s"]],[],[[45,46,"pl-s"],[46,52,"pl-c1"],[52,53,"pl-s"]],[[0,1,"pl-v"],[44,45,"pl-s"],[45,68,"pl-c1"],[68,69,"pl-s"]],[[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[29,30,"pl-s"],[30,48,"pl-c1"],[48,49,"pl-s"]],[[6,7,"pl-s"],[7,26,"pl-c1"],[26,27,"pl-s"],[42,43,"pl-s"],[43,64,"pl-c1"],[64,65,"pl-s"]],[[15,16,"pl-s"],[16,24,"pl-c1"],[24,25,"pl-s"]],[[26,27,"pl-s"],[27,64,"pl-c1"],[64,65,"pl-s"]],[[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"]],[[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"]],[[33,34,"pl-s"],[34,46,"pl-c1"],[46,47,"pl-s"],[50,51,"pl-s"],[51,63,"pl-c1"],[63,64,"pl-s"]],[[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[36,37,"pl-s"],[37,49,"pl-c1"],[49,50,"pl-s"]],[[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[45,46,"pl-s"],[46,52,"pl-c1"],[52,53,"pl-s"]],[[0,1,"pl-v"]],[[9,10,"pl-s"],[10,13,"pl-c1"],[13,14,"pl-s"],[24,25,"pl-s"],[25,27,"pl-c1"],[27,28,"pl-s"],[47,48,"pl-s"],[48,68,"pl-c1"],[68,69,"pl-s"]],[],[[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[32,33,"pl-s"],[33,45,"pl-c1"],[45,46,"pl-s"]],[[47,48,"pl-s"],[48,69,"pl-c1"],[69,70,"pl-s"]],[[38,39,"pl-s"],[39,48,"pl-c1"],[48,49,"pl-s"],[51,52,"pl-s"],[52,61,"pl-c1"],[61,62,"pl-s"],[64,65,"pl-s"],[65,76,"pl-c1"],[76,77,"pl-s"]],[[2,3,"pl-s"],[3,13,"pl-c1"],[13,14,"pl-s"],[16,17,"pl-s"],[17,28,"pl-c1"],[28,29,"pl-s"],[31,32,"pl-s"],[32,53,"pl-c1"],[53,54,"pl-s"]],[[45,46,"pl-s"],[46,69,"pl-c1"],[69,70,"pl-s"]],[[2,3,"pl-s"],[3,32,"pl-c1"],[32,33,"pl-s"]],[[61,62,"pl-s"],[62,78,"pl-c1"],[78,79,"pl-s"]],[[0,1,"pl-v"],[52,53,"pl-s"],[53,73,"pl-c1"],[73,74,"pl-s"]],[],[[65,66,"pl-s"],[66,82,"pl-c1"],[82,83,"pl-s"]],[[18,19,"pl-s"],[19,40,"pl-c1"],[40,41,"pl-s"]],[[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[72,73,"pl-s"],[80,81,"pl-s"]],[[11,12,"pl-s"],[12,22,"pl-c1"],[22,23,"pl-s"],[25,26,"pl-s"],[26,51,"pl-c1"],[51,52,"pl-s"],[54,55,"pl-s"],[55,79,"pl-c1"],[79,80,"pl-s"]],[[2,3,"pl-s"],[3,27,"pl-c1"],[27,28,"pl-s"],[59,60,"pl-s"],[60,73,"pl-c1"],[73,74,"pl-s"]],[[41,42,"pl-s"],[42,53,"pl-c1"],[53,54,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"]],[[3,4,"pl-s"],[4,42,"pl-c1"],[42,43,"pl-s"],[45,46,"pl-s"],[46,72,"pl-c1"],[72,73,"pl-s"]],[[9,10,"pl-s"],[10,21,"pl-c1"],[21,22,"pl-s"]],[[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"],[29,30,"pl-s"],[30,41,"pl-c1"],[41,42,"pl-s"]],[[30,31,"pl-s"],[31,36,"pl-c1"],[36,37,"pl-s"]],[[2,3,"pl-s"],[3,25,"pl-c1"],[25,26,"pl-s"],[43,44,"pl-s"],[44,48,"pl-c1"],[48,49,"pl-s"],[64,65,"pl-s"],[65,66,"pl-c1"],[66,67,"pl-s"]],[[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"],[49,50,"pl-s"],[50,51,"pl-c1"],[51,52,"pl-s"]],[[2,3,"pl-s"],[3,8,"pl-c1"],[8,9,"pl-s"]],[[14,18,"pl-s"],[15,18,"pl-corl"]],[[0,1,"pl-v"],[8,9,"pl-s"],[9,28,"pl-c1"],[28,29,"pl-s"],[47,48,"pl-s"],[48,57,"pl-c1"],[57,58,"pl-s"]],[],[],[],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[[0,11,"pl-mh"],[4,11,"pl-en"]],[],[[0,1,"pl-v"],[25,26,"pl-s"],[26,32,"pl-c1"],[32,33,"pl-s"],[44,45,"pl-s"],[45,55,"pl-c1"],[55,56,"pl-s"]],[],[],[[21,22,"pl-s"],[22,31,"pl-c1"],[31,32,"pl-s"]],[[0,1,"pl-v"]],[],[[0,1,"pl-v"],[52,53,"pl-s"],[53,67,"pl-c1"],[67,68,"pl-s"]],[],[],[],[[0,11,"pl-mh"],[4,11,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,16,"pl-c1"],[16,17,"pl-s"]],[],[[2,3,"pl-s"],[3,18,"pl-c1"],[18,19,"pl-s"]],[[0,1,"pl-v"]],[],[],[],[[0,9,"pl-mh"],[4,9,"pl-en"]],[],[[0,1,"pl-v"],[8,9,"pl-s"],[9,28,"pl-c1"],[28,29,"pl-s"]],[],[],[[0,1,"pl-v"]],[],[[2,3,"pl-s"],[3,19,"pl-c1"],[19,20,"pl-s"],[45,46,"pl-s"],[46,53,"pl-c1"],[53,54,"pl-s"]],[[6,7,"pl-s"],[7,32,"pl-c1"],[32,33,"pl-s"],[62,63,"pl-s"],[63,68,"pl-c1"],[68,69,"pl-s"]],[],[[0,1,"pl-v"],[8,9,"pl-s"],[9,42,"pl-c1"],[42,43,"pl-s"]],[],[],[],[],[[0,1,"pl-v"]],[[2,3,"pl-s"],[3,28,"pl-c1"],[28,29,"pl-s"],[34,35,"pl-s"],[35,62,"pl-c1"],[62,63,"pl-s"]],[],[],[[0,1,"pl-v"],[31,32,"pl-s"],[32,44,"pl-c1"],[44,45,"pl-s"]],[[2,3,"pl-s"],[3,30,"pl-c1"],[30,31,"pl-s"]],[],[[0,1,"pl-v"],[53,54,"pl-s"],[54,68,"pl-c1"],[68,69,"pl-s"]],[[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"],[22,23,"pl-s"],[23,34,"pl-c1"],[34,35,"pl-s"]],[],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,13,"pl-c1"],[13,14,"pl-s"],[57,58,"pl-s"],[58,64,"pl-c1"],[64,65,"pl-s"]],[[28,29,"pl-s"],[29,33,"pl-c1"],[33,34,"pl-s"]],[[35,36,"pl-s"],[36,40,"pl-c1"],[40,41,"pl-s"]],[[0,1,"pl-v"],[8,9,"pl-s"],[9,28,"pl-c1"],[28,29,"pl-s"]],[],[],[[0,1,"pl-v"],[8,9,"pl-s"],[9,32,"pl-c1"],[32,33,"pl-s"]],[[70,71,"pl-s"],[71,75,"pl-c1"],[75,76,"pl-s"]],[],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[[0,1,"pl-v"]],[[0,1,"pl-v"],[8,9,"pl-s"],[9,29,"pl-c1"],[29,30,"pl-s"],[35,36,"pl-s"],[36,57,"pl-c1"],[57,58,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[],[[0,1,"pl-v"]],[[0,1,"pl-v"]],[],[],[[0,1,"pl-v"],[35,36,"pl-s"],[36,49,"pl-c1"],[49,50,"pl-s"]],[],[[0,1,"pl-v"]],[],[[0,1,"pl-v"]],[],[]],"colorizedLines":null}},"title":"patchrail/CHANGELOG.md at v0.5.0 · patchrail/patchrail","appPayload":{},"meta":{"title":"patchrail/CHANGELOG.md at v0.5.0 · patchrail/patchrail"}}</script>
  <div data-target="react-app.reactRoot"><meta name="github-code-view-meta-stats" id="github-code-view-meta-stats" data-hydrostats="publish"/> <!-- --> <a hidden="" id="code-view-repo-link" href="/patchrail/patchrail" data-discover="true"></a> <div class="d-none"></div><div><div style="--spacing:var(--spacing-none)" class="prc-PageLayout-PageLayoutRoot--KH-d" data-component="SplitPageLayout" data-has-sidebar="true"><div class="prc-PageLayout-SidebarWrapper-kLG4B CopilotSidePanelSidebar-module__SidePanel__L3O0C CopilotSidePanelSidebar-module__HiddenSidePanel__TBRGn" style="--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="end" data-sticky="true" data-responsive-variant="fullscreen"><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-SidebarVerticalDivider-0Rl0V" data-component="PageLayout.VerticalDivider" data-variant="line" data-position="end" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="450" aria-valuemax="768" aria-valuenow="544" aria-valuetext="Pane width 544 pixels" tabindex="0"></div></div><div class="prc-PageLayout-Sidebar-iciWg" data-component="SplitPageLayout.Sidebar" data-resizable="true" style="--spacing:var(--spacing-normal);--pane-min-width:450px;--pane-max-width:768px;--pane-width-custom:544px;--pane-width-size:var(--pane-width-custom);--pane-width:544px"><div class="height-full" data-testid="copilot-code-view-side-panel"><div id="copilot-side-panel-content" class="height-full"></div></div></div></div><div class="prc-PageLayout-PageLayoutWrapper-2BhU2" data-width="full"><div class="prc-PageLayout-PageLayoutContent-BneH9"><div id="repos-file-tree-sidebar" class="CodeViewFileTreeLayout-module__sidebar__n_Aau" tabindex="0"><div class="prc-PageLayout-PaneWrapper-pHPop ReposFileTreePane-module__Pane__rBZpI ReposFileTreePane-module__HideTree__AYZnm ReposFileTreePane-module__HidePane__VHAVt" style="--offset-header:0px;--spacing-row:var(--spacing-none);--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="start" data-sticky="true"><div class="prc-PageLayout-HorizontalDivider-JLVqp prc-PageLayout-PaneHorizontalDivider-9tbnE" data-component="PageLayout.HorizontalDivider" data-variant-regular="none" data-variant-narrow="none" data-position="start" style="--spacing-divider:var(--spacing-none);--spacing:var(--spacing-none)"></div><div class="prc-PageLayout-Pane-AyzHK" data-component="SplitPageLayout.Pane" data-resizable="true" style="--spacing:var(--spacing-none);--pane-min-width:256px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));--pane-width-size:var(--pane-width-large);--pane-width:320px"></div><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-PaneVerticalDivider-le57g" data-component="PageLayout.VerticalDivider" data-variant-narrow="none" data-variant-regular="line" data-variant-wide="line" data-position="start" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="256" aria-valuemax="600" aria-valuenow="320" aria-valuetext="Pane width 320 pixels" tabindex="0"></div></div></div></div><div data-component="SplitPageLayout.Content" class="prc-PageLayout-ContentWrapper-gR9eG"><div class="prc-PageLayout-Content-xWL-A" data-width="full" style="--spacing:var(--spacing-none)"><div class="SharedPageLayout-module__content__IwGAp" data-selector="repos-split-pane-content" id="repos-split-pane-content" tabindex="0"> <!-- --> <div class="container CodeViewHeader-module__Box__JkPOb"><div class="CodeViewHeader-module__StickyHeader__Qn7UN" id="StickyHeader"><div class="CodeViewHeader-module__Box_1__SbNDV"><div class="CodeViewHeader-module__Box_2__TB46f"><div class="react-code-view-header-wrap--narrow CodeViewHeader-module__Box_3__q1zUL"><div class="CodeViewHeader-module__treeToggleWrapper__RQ__9"><h2 class="use-tree-pane-module__Heading__s4QbZ prc-Heading-Heading-MtWFE" data-component="Heading"><button data-component="Button" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="prc-Button-ButtonBase-9n-Xk ExpandFileTreeButton-module__Button_1__Svs95" data-loading="false" data-size="medium" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Files</span></span></button><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-9n-Xk position-relative ExpandFileTreeButton-module__expandButton__hDOcv ExpandFileTreeButton-module__filesButtonBreakpoint__zEvz3 fgColor-muted prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_4lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><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.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="se" data-component="Tooltip" aria-hidden="true" id="_R_4lla9lik5_">Expand file tree</span><div class="d-none"></div></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="v0.5.0 branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">v0.5.0</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="react-code-view-header-mb--narrow CodeViewHeader-module__Box_5__MQ0hL"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__lg__Rjz0A"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/patchrail/patchrail/tree/v0.5.0" data-discover="true">patchrail</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__lg__Rjz0A prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="file-name-id">CHANGELOG.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lla9lik5_"><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="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lla9lik5_">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><div><div class="CodeViewHeader-module__FileResultsList__JDzUy"><span class="d-flex FileResultsList-module__FilesSearchBox__ivVkc TextInput-wrapper prc-components-TextInputWrapper-Hpdqi prc-components-TextInputBaseWrapper-wY-n0" data-no-trailing-action="true" data-component="TextInput" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id="_R_1cpla9lik5_" aria-hidden="true" data-component="TextInput.LeadingVisual"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellCheck="false" placeholder="Go to file" aria-describedby="_R_1cpla9lik5_ _R_1cpla9lik5H1_" data-component="input" class="prc-components-Input-IwWrt" value=""/><span class="TextInput-icon" id="_R_1cpla9lik5H1_" aria-hidden="true" data-component="TextInput.TrailingVisual"></span></span></div><div class="d-none"></div></div><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7p9la9lik5_" id="_R_99la9lik5_"><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="nw" data-component="Tooltip" aria-hidden="true" id="_R_7p9la9lik5_">More file actions</span></div></div></div><div class="react-code-view-header-element--narrow"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7pdla9lik5_" id="_R_9dla9lik5_"><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="nw" data-component="Tooltip" aria-hidden="true" id="_R_7pdla9lik5_">More file actions</span></div></div></div></div></div></div></div><div class="CodeView-module__contentWrapper__cG2JH"><div class="react-code-view-bottom-padding"><div class="BlobTopBanners-module__Box__v_nvx"></div></div> <div class="d-none"></div><div class="d-flex flex-column border rounded-2 tmp-mb-3 pl-1"><div class="LatestCommit-module__Box__B25ZT"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">History</h2><a data-component="LinkButton" href="/patchrail/patchrail/commits/v0.5.0/CHANGELOG.md" class="prc-Button-ButtonBase-9n-Xk d-none d-lg-flex LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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></span><span data-component="text" class="prc-Button-Label-FWkx3"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><a data-component="LinkButton" aria-label="View commit history for this file." href="/patchrail/patchrail/commits/v0.5.0/CHANGELOG.md" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby="_R_4mlala9lik5_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><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></span></span></a><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" role="tooltip" aria-hidden="true" id="_R_4mlala9lik5_">History</span></div></div></div></div></div><div class="d-flex flex-row"><div class="container BlobViewContent-module__blobContainer__DtH2d"><div class="react-code-size-details-banner BlobViewContent-module__codeSizeDetails__e5sUw"><div class="react-code-size-details-banner CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="25.2 KB" style="--truncate-max-width:100%"><span>409 lines (372 loc) · 25.2 KB</span></div></div></div></div><div class="react-blob-view-header-sticky BlobViewContent-module__stickyHeader__VwxB5" id="repos-sticky-header"><div class="BlobViewHeader-module__Box__yhm9u"><div class="react-blob-sticky-header"><div class="FileNameStickyHeader-module__outerWrapper__ZL4Xc FileNameStickyHeader-module__outerWrapperHidden__Zpynk"><div class="FileNameStickyHeader-module__Box_1__Hazu5"><div class="FileNameStickyHeader-module__Box_2__hoolP"><div class="FileNameStickyHeader-module__Box_3__MVKsk"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="v0.5.0 tag" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-tag" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">v0.5.0</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="FileNameStickyHeader-module__Box_4__FLhtt"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__md__Wb1Gs"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/patchrail/patchrail/tree/v0.5.0" data-discover="true">patchrail</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__md__Wb1Gs prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="sticky-file-name-id">CHANGELOG.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lcpala9lik5_"><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="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lcpala9lik5_">Copy path</span></div></div></div><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk FileNameStickyHeader-module__Button__LSEU_ FileNameStickyHeader-module__GoToTopButton__nxAFn" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Top</span></span></button></div></div></div><div class="BlobViewHeader-module__Box_1__VEmuQ"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">File metadata and controls</h2><div class="BlobViewHeader-module__Box_2__icUs2"><ul aria-label="File view" class="prc-SegmentedControl-SegmentedControl-lqIXp BlobTabButtons-module__SegmentedControl__jen2u" data-variant="default" data-size="small" data-component="SegmentedControl"><li class="prc-SegmentedControl-Item-tSCQh" data-selected="" data-component="SegmentedControl.Button"><button aria-pressed="true" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:transparent"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><div class="d-none"></div><div class="react-code-size-details-in-header CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="25.2 KB" style="--truncate-max-width:100%"><span>409 lines (372 loc) · 25.2 KB</span></div></div></div></div><div class="BlobViewHeader-module__Box_3__ng6v2"><div class="d-none"></div><div class="react-blob-header-edit-and-raw-actions BlobViewHeader-module__Box_4__J4Y4W"><div class="d-none"></div><div class="prc-ButtonGroup-ButtonGroup-vFUrY" data-component="ButtonGroup"><div class="prc-ButtonGroup-Item-PqvDl"><a data-component="LinkButton" href="https://github.com/patchrail/patchrail/raw/refs/tags/v0.5.0/CHANGELOG.md" data-testid="raw-button" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov BlobViewHeader-module__LinkButton__X9kx2" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Raw</span></span></a></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="copy-raw-button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_qaucpala9lik5_"><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="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_qaucpala9lik5_">Copy raw file</span></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="download-raw-button" class="prc-Button-ButtonBase-9n-Xk BlobViewHeader-module__downloadButton__ef459 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_eaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_eaucpala9lik5_">Download raw file</span></div></div></div><button data-component="IconButton" type="button" aria-pressed="false" class="prc-Button-ButtonBase-9n-Xk tmp-mr-2 TableOfContents-module__IconButton__jrlNM prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_3ucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_3ucpala9lik5_">Outline</span><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click BlobViewHeader-module__IconButton__XrMQY prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_fkecpala9lik5_" id="_R_kecpala9lik5_"><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="nw" data-component="Tooltip" aria-hidden="true" id="_R_fkecpala9lik5_">Edit and raw actions</span></div></div></div></div><div></div></div><div class="BlobViewContent-module__blobContentWrapper__JS0W6"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="BlobContent-module__blobContentSection__VOgZq BlobContent-module__blobContentSectionMarkdown__mPLOK" style="margin-top:46px"><div class="js-snippet-clipboard-copy-unpositioned BlobContent-module__markdownBlob__T8jpG" data-hpc="true" containertiming="hpc"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Changelog</h1><a id="user-content-changelog" class="anchor" aria-label="Permalink: Changelog" href="#changelog"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">0.5.0 - 2026-07-14</h2><a id="user-content-050---2026-07-14" class="anchor" aria-label="Permalink: 0.5.0 - 2026-07-14" href="#050---2026-07-14"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Fixed</h3><a id="user-content-fixed" class="anchor" aria-label="Permalink: Fixed" href="#fixed"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>
<p dir="auto"><strong>A tool the job merely <em>named</em> can no longer outrank the one that failed.</strong> Found by
running <code>ci explain</code> over real failing runs from public repositories. Three of nine —
encode/httpx, prefecthq/prefect and home-assistant/core — were decided by the job's cast
list rather than its cause of death:</p>
<ul dir="auto">
<li><code>scripts/check</code>-style CI shells run under <code>set -x</code>, so every command is echoed into
the log, passing or not. httpx's echo of <code>ruff check</code> (a run that <em>passed</em>), plus
<code>F401</code> quoted inside ruff's non-fatal warning about a malformed noqa directive, made a
plain <code>1 failed, 1416 passed</code> pytest failure come out as <code>python_lint</code> at 0.71.</li>
<li>pip announces every dev dependency it resolves, so <code>Collecting mypy==1.17.1</code> puts
<code>mypy</code> in the log of a job that never type-checked anything. Prefect's pytest
collection error came out as <code>python_type_check</code>.</li>
</ul>
<p dir="auto">Signals are now judged by the <em>line</em> they land on: a rule whose every signal appears
only on a <code>set -x</code> echo, an Actions step header (<code>Run …</code>) or a pip install line has
watched a tool get named, never fail, and defers to a rule that matched a real error.
Scoring itself is unchanged, so an invocation sitting next to a genuine error still
corroborates it and keeps it at full confidence — a real dotnet, helm or php failure
scores exactly as before. This generalises <code>INVOCATION_ONLY_PATTERNS</code>, which had to name
every tool one pattern at a time and switched itself off entirely as soon as a single
signal fell outside the list.</p>
</li>
<li>
<p dir="auto"><strong><code>python_test_failure</code> now recognises pytest's own verdict.</strong> The rule could match a
<em>named</em> failing test (<code>FAILED x::y</code>) or a bare <code>pytest</code> invocation, but not
<code>===== 1 failed, 1416 passed in 18.37s =====</code>, <code>short test summary info</code>, or a
collection error (<code>ERROR tests/x.py - ValueError</code>). A run that reported the count and
not the names — <code>-q</code>, or any plugin that rewrites the summary — was therefore carried by
its invocation alone and lost to whatever tool the job had merely mentioned. The <code>=</code>
run and the <code>in 12.3s</code> tail are pytest's summary line and not jest's, so node test
failures are unaffected.</p>
</li>
<li>
<p dir="auto"><strong>ANSI colour codes no longer hide the failure.</strong> CI tools colour their output and CI
keeps the colour on (Airflow runs pytest with <code>--color=yes</code>, cargo honours
<code>CARGO_TERM_COLOR=always</code>, jest and eslint colour by default), and the GitHub log API
serves those escapes back with the ESC byte written out as the two literal characters
<code>^[</code>. The colour reset lands <em>inside</em> the failure line — <code>^[[31mFAILED^[[0m tests/…::…</code>
— so <code>FAILED .*::</code> and every other pattern spanning a coloured token silently stopped
matching. A real apache/airflow test failure was reported as <code>artifact_or_cache_failure</code>
because the only signal left uncoloured was the bare <code>pytest</code> invocation. Both
encodings (real <code>\x1b</code> and literalised <code>^[</code>) are now stripped before matching; the strip
is anchored to the escape introducer, so <code>error[E0277]</code>, <code>[ERROR]</code> and ordinary
indexing are untouched.</p>
</li>
<li>
<p dir="auto"><strong>Post-failure cleanup noise no longer outranks the real cause.</strong> <code>actions/upload-artifact</code>
appears in every job that uploads anything, and "No files were found with the provided
path" is a <em>warning</em> it emits when its glob matches nothing (it says so itself: "No
artifacts will be uploaded"). Together they fire on the commonest shape in CI — a test
fails, and the <code>if: failure()</code> step uploading logs for diagnosis finds nothing — which
tied the real cause and beat it on declaration order. A rule carried only by such
signals now defers to one that matched an actual error. A genuine artifact or cache
failure is unaffected: it trips a terminal signal ("Failed to CreateArtifact",
"Unable to download artifact", "Cache service responded with 500").</p>
</li>
<li>
<p dir="auto">The classifier no longer reads a command that merely <em>ran</em> as the failure. Three
bugs of the same shape, all found by running <code>ci explain</code> over real failing runs
from public repositories rather than over the fixture zoo:</p>
<ul dir="auto">
<li><code>\btsc\b</code> matched the x86 <strong>time stamp counter</strong> in the <code>flags :</code> line of
<code>/proc/cpuinfo</code>, which perf-sensitive projects dump into their log preamble.
A real rust-lang/rust build failure came back as <code>typescript_typecheck</code> on the
strength of a CPU feature name. <code>tsc</code> now only counts in command position
(<code>pnpm tsc</code>, <code>&gt; tsc --noEmit</code>, <code>npx tsc</code>, <code>tsc -p …</code>) or before a flag/verb.</li>
<li><code>docker build</code> / <code>docker buildx build</code> / <code>docker compose</code> appear in every job
that builds a container as a setup step, and <code>cargo test</code> / <code>clippy</code> appear in
the command line of every Rust CI job, passing or not. A rule matching <em>only</em>
such signals now defers to a rule that matched an actual error, reusing the
deferral already in place for ambiguous network signals. They still count
toward confidence when a real error sits beside them, so a genuine docker or
clippy failure is unchanged.</li>
<li>Because scoring is by matched-pattern count, one bogus signal was enough to tie
the rule that matched the real error and beat it on declaration order alone.
The zoo missed all of this: its fixtures are clean, and a real log is not — the
same <code>error[E0277]</code> that a fixture classifies correctly was misread in the wild
because the job also happened to run <code>docker buildx build</code>.
No fixture changes classification or confidence (221 fixtures, top-1 1.0).</li>
</ul>
</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Added</h3><a id="user-content-added" class="anchor" aria-label="Permalink: Added" href="#added"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>patchrail schema ci-classes</code> now serves a published schema for
<code>ci classes --format json</code>, and the suite validates real output against it.
It was the one JSON command with no schema, no conformance test and no
cookbook entry — which is why 0.4.0 could move it from
<code>patchrail.ci_classes.v1</code> to <code>.v2</code> in a minor bump without anything going
red, and why the break reached consumers (this project's own GitHub Action
among them) silently. Changing the contract now means shipping the schema
that describes it: <code>test_schema_conformance.py</code> compares the <code>schema_version</code>
the CLI emits against the <code>const</code> in the schema a user can fetch, so the two
cannot drift apart again. The schema also encodes the v2 rule itself —
<code>unknown</code> is valid under <code>fallback</code> and rejected inside <code>classes</code> — so
putting the sentinel back into the denominator fails validation.</li>
<li><code>docs/json-cookbook.md</code> documents the <code>ci classes</code> payload with a coverage
recipe (which supported classes has a log corpus never exercised?), and its
sample output is pinned to the code by <code>test_readme_claims.py</code> in both
directions, like the README's counts.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">0.4.0 - 2026-07-14</h2><a id="user-content-040---2026-07-14" class="anchor" aria-label="Permalink: 0.4.0 - 2026-07-14" href="#040---2026-07-14"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Minor bump rather than a patch: <code>ci classes --format json</code> changes its contract.
<code>schema_version</code> is now <code>patchrail.ci_classes.v2</code> and <code>unknown</code> left <code>classes</code>
and <code>count</code> (see Fixed). Scripts pinned to the v1 shape need a one-line update.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Fixed</h3><a id="user-content-fixed-1" class="anchor" aria-label="Permalink: Fixed" href="#fixed-1"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>patchrail ci classes</code> no longer counts <code>unknown</code> as a supported failure
class. It reported "41 supported failure classes" and listed <code>unknown</code> — with
a reproduction command — alongside the 40 real ones, contradicting the README,
the docs and the fixture benchmark, all of which say 40. <code>unknown</code> is what
<code>ci explain</code> returns when <em>no</em> rule matches, so a coverage script following the
README (<code>ci classes --format json</code>) was dividing by a denominator containing an
entry it could never cover. The sentinel is still reported, under a new
<code>fallback</code> key, and named in the text and markdown output; it is just out of
<code>classes</code> and <code>count</code>. JSON consumers: <code>schema_version</code> is now
<code>patchrail.ci_classes.v2</code>.</li>
<li>README: the redaction bullet advertised 23 secret-redaction patterns; the
shipped table has 24. The class, fixture and redaction counts the README
advertises are now derived from the code by <code>tests/test_readme_claims.py</code>, so
they fail the build instead of going stale (the fixture count was already
pinned by tests, and it was the only one of the three that had stayed correct).</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Changed</h3><a id="user-content-changed" class="anchor" aria-label="Permalink: Changed" href="#changed"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>patchrail ci explain</code>/<code>classify</code> now print a first-use hint when the log
input is empty or whitespace-only. The common cause is the README one-liner
<code>gh run view --log-failed | patchrail ci explain</code> pointed at a run whose logs
GitHub already expired (or a run that has not failed), which pipes in nothing.
The error keeps its exit code <code>2</code> and clean stdout; it just adds a line
telling the user to point it at a <em>recent</em> failed run instead of leaving them
guessing. Non-empty input is completely unaffected.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">0.3.1 - 2026-07-11</h2><a id="user-content-031---2026-07-11" class="anchor" aria-label="Permalink: 0.3.1 - 2026-07-11" href="#031---2026-07-11"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Added</h3><a id="user-content-added-1" class="anchor" aria-label="Permalink: Added" href="#added-1"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>patchrail ci explain</code>/<code>classify</code> now turn an <code>unknown</code> result into a
contribution on-ramp: the text and markdown reports append one line pointing
the maintainer at the <code>ci_failure_fixture</code> issue template
(<code>.../issues/new?template=ci_failure_fixture.md</code>) so an unrecognized log
becomes a fixture request instead of a dead-end. The classifier's behavior
and JSON output are unchanged — the pointer is presentation-only and appears
solely when <code>failure_class == "unknown"</code>.</li>
<li><code>patchrail -V</code> is now a short alias for <code>--version</code>. Both print
<code>patchrail &lt;version&gt;</code> and exit <code>0</code>, matching the conventional single-letter
flag most CLIs expose (handy in bug reports and CI logs).</li>
<li>New <code>tests/test_schema_conformance.py</code> validates real CLI output against
<code>src/patchrail/schemas/*.v1.schema.json</code> with <code>jsonschema</code> (dev-only
dependency; the installed package still ships with zero runtime
dependencies). Previously <code>_load_schema()</code> only read schema files as text
to print them via <code>patchrail ci schema</code>; nothing checked that a payload
builder's output still matched its schema. Covers <code>ci-result</code> (every
fixture in <code>examples/ci-triage/</code>, 221 cases), <code>ci-benchmark</code>, and
<code>ci-fixture-check</code>.</li>
<li><code>mypy --strict</code> now runs on <code>src/patchrail/ci/classify.py</code> (the classifier
engine) as a dev dependency and a CI step, alongside <code>ruff check</code>/<code>ruff format --check</code>. The module already passed strict type checking with no
changes required; this locks that in against regressions. See
<code>[tool.mypy]</code> in <code>pyproject.toml</code>.</li>
<li>New sanitized <code>github-actions-cmake-gcc-compile-error</code> fixture covers a real
CMake + g++ undeclared-identifier link failure for <code>cpp_build_failure</code>, which
previously had a classifier rule but no fixture in the benchmark zoo despite
the README advertising C++ support. Bringing the benchmark zoo to 220 cases.</li>
<li><code>java_build_failure</code> now also recognises kotlinc's own diagnostic format
(<code>e: File.kt: (line, col): ...</code>), <code>Unresolved reference:</code>, and Kotlin Gradle
task failures (<code>:compileDebugKotlin FAILED</code>). A maintainer pasting only the
kotlinc excerpt of a Kotlin/Android CI failure — without the Gradle
<code>Execution failed for task</code> / <code>BUILD FAILED</code> banner further down the log —
previously fell through to <code>unknown</code> at 0.15 confidence. New sanitized
<code>github-actions-kotlin-compile-excerpt-no-banner</code> fixture guards this,
bringing the benchmark zoo to 221 cases.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Fixed</h3><a id="user-content-fixed-2" class="anchor" aria-label="Permalink: Fixed" href="#fixed-2"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>patchrail ci explain</code>/<code>classify</code> now normalize the GitHub Actions log line
prefix before classifying, so the common one-liner
<code>gh run view &lt;run-id&gt; --log-failed --repo &lt;owner/repo&gt; | patchrail ci explain</code>
classifies identically to a saved raw log. <code>gh</code> prefixes every line with
<code>&lt;job&gt;\t&lt;step&gt;\t&lt;timestamp&gt;</code> (and a UTF-8 BOM on the first line), which shifted
real content off the start of the line and silently defeated the classifier's
line-anchored (<code>^</code>) patterns — dropping confidence (e.g. <code>go_lint</code> and
<code>node_test_failure</code> fell from <code>0.95</code> to <code>0.89</code> on sparse logs). The raw
Actions log-download form (<code>&lt;timestamp&gt; &lt;line&gt;</code>) is normalized too. Regression
cases in <code>tests/test_ci_classify_expansion.py</code> pin gh-prefixed == raw.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Changed</h3><a id="user-content-changed-1" class="anchor" aria-label="Permalink: Changed" href="#changed-1"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Extracted the entire <code>funded-issues</code> subcommand group (20 argparse handlers,
~50 markdown/text/CSV/JSONL renderers, and the argparse wiring for all 20
sub-subcommands — 3853 of <code>cli.py</code>'s 10368 lines) into a new
<code>src/patchrail/cli_funded.py</code> module, registered from <code>_build_parser()</code> via
<code>cli_funded.register(subparsers)</code>. No behavior change: same commands, same
flags, same output. <code>cli.py</code> drops from 10368 to ~5650 lines. If you import
<code>patchrail.cli._normalize_recheck_observation</code> or similar funded-issues
internals directly (rather than going through the public CLI), import from
<code>patchrail.cli_funded</code> instead.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">0.3.0 - 2026-07-09</h2><a id="user-content-030---2026-07-09" class="anchor" aria-label="Permalink: 0.3.0 - 2026-07-09" href="#030---2026-07-09"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Fixed</h3><a id="user-content-fixed-3" class="anchor" aria-label="Permalink: Fixed" href="#fixed-3"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Deterministic Go test failures are no longer misread as
<code>network_transient_failure</code> when their logs contain incidental
network-shaped noise (<code>dial tcp</code>, <code>connection refused</code>, <code>context deadline exceeded</code>, <code>i/o timeout</code>). The classifier now defers a broad transient-network
match built <em>entirely</em> from these ambiguous signals to the concrete failure
when one also matched, so a real bug isn't mislabeled "just retry". Genuine
outages still classify as transient because they trip a terminal signal (DNS
resolution, rate limit, gateway error, TLS handshake, or a git remote hang-up)
outside the ambiguous set. <code>go_test_failure</code> also now recognises the canonical
<code>--- FAIL:</code> marker. New <code>go-integration-test-network-noise</code> fixture guards this,
bringing the benchmark zoo to 208 cases.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Added</h3><a id="user-content-added-2" class="anchor" aria-label="Permalink: Added" href="#added-2"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>patchrail --version</code> now prints the installed version (e.g. <code>patchrail 0.3.0</code>)
and exits, so a maintainer can confirm which release they are running without
invoking a subcommand.</li>
<li><code>java_build_failure</code> now also recognises <strong>sbt</strong> (Scala on the JVM). sbt prints
none of the Maven/Gradle banners the rule keyed on, so a genuine
<code>(project / Test / compileIncremental) Compilation failed</code> — or an
<code>sbt.TestsFailedException</code> — previously fell through to <code>unknown</code>. New signals
cover the sbt session banner, incremental-compile failure, Scala
<code>not found: value</code>/<code>not found: type</code> errors, and the sbt test-failure
exception; the reproduction command now suggests <code>sbt test</code>. New sanitized
<code>github-actions-sbt-scala-compile</code> fixture (modelled on a real
<code>scalatest/scalatest</code> GitHub Actions run) guards this, bringing the benchmark
zoo to 209 cases.</li>
<li>New sanitized <code>ruby-rspec-parallel-failure</code> fixture captures a real
<code>rubocop/rubocop</code> RSpec failure tail (parallel/turbo_tests summary with
<code>pending</code> before <code>failures</code>), bringing the benchmark zoo to 207 cases.</li>
<li>New <code>xcode_build_failure</code> class classifies Apple-platform build and test
failures from <code>xcodebuild</code>, <code>swift build</code>/<code>swift test</code>, and Swift Package
Manager — Swift compile errors, missing modules (<code>error: no such module</code>),
unresolved package dependencies, and XCTest failures (<code>** BUILD FAILED **</code>,
<code>** TEST FAILED **</code>, <code>The following build commands failed:</code>). Backed by three
sanitized fixtures in <code>examples/ci-triage/</code>, bringing the benchmark zoo to 169
cases and the classifier to 40 failure classes.</li>
<li>New <code>docs_build_failure</code> class classifies documentation-site build failures
from Sphinx (<code>sphinx-build -W</code> warnings-as-errors, missing toctree entries),
MkDocs (<code>mkdocs build --strict</code> broken links), and Docusaurus (<code>docusaurus build</code> broken links). Backed by three sanitized fixtures in
<code>examples/ci-triage/</code>, bringing the benchmark zoo to 166 cases.</li>
<li><code>patchrail ci classes</code> lists every supported failure class with its likely
subsystem and reproduction command (plus the <code>unknown</code> fallback), in stable
order. Supports <code>--format text|json|markdown</code> and <code>--out</code>, so the set of
classes the classifier can diagnose is discoverable from the CLI instead of
only in the source. Closes #150.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Fixed</h3><a id="user-content-fixed-4" class="anchor" aria-label="Permalink: Fixed" href="#fixed-4"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Real RSpec failures now classify as <code>ruby_bundle_failure</code> instead of
<code>unknown</code>. RSpec prints its rerun list as <code>rspec ./path/to/thing_spec.rb[…]</code>
and its summary as <code>N examples, [K pending, ]M failures</code> (rspec, parallel and
turbo_tests) — neither of which the old <code>rspec .*failures?</code> pattern matched,
so a pasted spec-failure tail without bundler setup lines fell through to
<code>unknown</code>. Two shape-matching patterns were added to the rule. Surfaced by
dogfooding a real <code>rubocop/rubocop</code> CI run.</li>
<li>Python CI logs no longer misclassify as <code>python_dependency_resolution</code> just
because they run <code>python -m pip install</code>. That bare command line was a
detection pattern, but it appears in almost every Python CI job regardless of
what actually failed, so any failing Python job with no stronger signal was
reported as a dependency-resolution conflict with the misleading "pin or relax
the conflicting dependency range" advice. Dogfooded against a real
<code>pandas-dev/pandas</code> 32-bit CI run whose <code>pip install</code> failed at
<code>metadata-generation-failed</code> (a package build error, <code>Rust not found</code>) — it was
reported as <code>python_dependency_resolution</code> (0.53). The boilerplate pattern is
dropped, so a build/metadata failure with no genuine resolution signal now
stays honest (<code>unknown</code>) instead. To keep recall on real conflicts, two
genuine pip signals were added: pip's actual Requires-Python wording
(<code>requires a different Python:</code>) and its no-distribution <code>(from versions: …)</code>
line; the three synthetic no-matching-distribution fixtures were updated to
include the real <code>(from versions: …)</code> output pip prints. Benchmark stays at
206/206 top-1 with all confidence floors met; the bundled dependency-failure
demo now reports 0.89 (three genuine resolution signals) instead of 0.95.
Regression covered in <code>tests/</code>.</li>
<li><code>patchrail ci explain</code>/<code>classify</code> no longer hangs on large CI logs. The
<code>github_actions_workflow</code> rule paired two unanchored lookaheads
(<code>(?=[\s\S]*.github/workflows/…)(?=[\s\S]*Invalid workflow file…)</code>); under
<code>re.search</code> that compound is retried at every start position, so a log that
mentions <code>.github/workflows/*.yml</code> (every <code>actions/checkout</code> step does) but not
a workflow-error phrase drove the matcher into O(n²) backtracking and pegged a
core at 100% for minutes. Dogfooded against a real <code>cli/cli</code> Go CI run
(~200 KB) that never returned. The lookahead is now anchored with <code>\A</code> so it is
evaluated once, in linear time; the "workflow path AND error phrase present"
signal is unchanged. Regression covered in <code>tests/</code>.</li>
<li>Rust CI failures no longer misclassify as <code>node_dependency_install</code>,
<code>dotnet_build_failure</code>, or <code>java_build_failure</code> because of generic boilerplate.
The <code>Swatinem/rust-cache</code> action prints <code>Lockfiles considered:</code> (which matched
the old bare <code>lockfile</code> node signal) and cargo prints <code>build failed, waiting for other jobs to finish</code> (which matched the case-insensitive <code>Build FAILED</code> /
<code>BUILD FAILED</code> banners). The node lockfile signal now requires a whole-word
<code>lockfile</code>, and the .NET/Gradle banners are matched case-sensitively so they
fire only on the tool's actual <code>Build FAILED</code> / <code>BUILD FAILED</code> output. A real
<code>tokio-rs/tokio</code> rustdoc failure (<code>error[E0433]</code>) now classifies as
<code>rust_test_failure</code>. Regression covered in <code>tests/</code>.</li>
<li>Sharper reproduce commands for three failure classes surfaced by <code>patchrail ci classes</code> / <code>ci explain</code>. <code>node_script_missing</code> no longer suggests <code>npm run build</code> (which just re-triggers the "missing script" error) and instead runs
<code>npm run</code> to list the scripts <code>package.json</code> actually defines, so you can
compare against the one your workflow calls. <code>security_scan_failure</code> names the
concrete scanners to rerun locally (<code>npm audit</code>, <code>pip-audit</code>, <code>cargo audit</code>,
<code>trivy fs .</code>, <code>bandit -r .</code>, <code>semgrep --config auto</code>) instead of the generic
"rerun the failing security scan locally". <code>github_actions_workflow</code> points at
<code>actionlint .github/workflows/</code>, which validates workflow syntax and action
refs locally, rather than only printing the YAML back with <code>gh workflow view</code>.</li>
<li>Real GitHub Actions logs no longer misclassify as <code>git_checkout_failure</code> when
checkout actually succeeded. The rule dropped three boilerplate signals that
appear in almost every Actions log regardless of outcome — the <code>actions/checkout</code>
setup step, the <code>git submodule foreach</code> post-job cleanup line, and a bare
<code>git-lfs</code> mention — keeping only genuine checkout/clone/submodule/LFS <em>failure</em>
markers (<code>fatal: ...</code>, <code>Failed to fetch submodule</code>, <code>smudge filter lfs failed</code>,
<code>error downloading object</code>, …). Dogfooded against a real <code>pallets/flask</code> CI run
whose pytest jobs failed on a conftest <code>SyntaxError</code> but were reported as a git
checkout problem.</li>
<li><code>python_test_failure</code> now also recognizes pytest collection failures
(<code>ImportError while loading conftest ...</code>, <code>N errors during collection</code>), so a
broken <code>conftest.py</code> or import-time error surfaces as a test failure with the
<code>python -m pytest -q</code> reproduce line instead of falling through to a weaker or
wrong class.</li>
<li><code>patchrail ci explain</code> and <code>ci classify</code> now fail clearly on empty or
whitespace-only input (from <code>--log</code> or stdin) instead of silently reporting
<code>failure_class: unknown</code> with confidence <code>0.15</code> and exit code <code>0</code>. They print
<code>log input is empty</code> to stderr, exit with code <code>2</code>, and write nothing to
<code>--out</code>, so a bad shell redirect is no longer mistaken for an unclassifiable
log. Closes #151.</li>
<li>Added <code>node_script_missing</code> to the published <code>ci-result</code> schema enum; the
classifier could already emit it, so a valid classification previously failed
schema validation for downstream consumers. A new test guards that every rule
class is declared in the schema enum.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">0.2.0 - 2026-07-07</h2><a id="user-content-020---2026-07-07" class="anchor" aria-label="Permalink: 0.2.0 - 2026-07-07" href="#020---2026-07-07"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Removed</h3><a id="user-content-removed" class="anchor" aria-label="Permalink: Removed" href="#removed"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Removed the commercial <code>Guide:</code> link that <code>ci explain</code> appended to text and
Markdown reports, and the matching guide URL outputs from the GitHub Action.
Reports now end after the classification; per-class remediation write-ups
live in-repo under <code>docs/fix/</code>.</li>
<li>Removed commercial product links and campaign-tagged URLs from the README,
docs, and the PyPI project URL list.</li>
<li>Removed the distribution and web-metrics tooling (<code>ci share-links</code> and the
web metrics commands and store). PatchRail no longer ships link-tracking or
distribution helpers.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Changed</h3><a id="user-content-changed-2" class="anchor" aria-label="Permalink: Changed" href="#changed-2"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>funded-issues</code> is now explicitly labeled experimental. Discovery commands
default to safe-only filtering, and risky entries require an explicit
<code>--include-risky</code> flag.</li>
<li>Rewrote the README around the open-source CI triage workflow: quickstart
with real classifier output, honest feature table, local-first safety
section, and the fixture contribution path.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Added</h3><a id="user-content-added-3" class="anchor" aria-label="Permalink: Added" href="#added-3"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Added <code>node_script_missing</code> CI classification so npm/pnpm/yarn jobs that
call a missing package script are separated from dependency-install failures
and routed to a workflow/script repair path.</li>
<li>Added a permanent source-level blocklist to the funded-issues tracker:
owners manually verified as fake-bounty sources are dropped at the
<code>merge_into_store</code> choke point (counted as <code>blocked</code> in the merge summary)
and <code>purge_blocklisted_entries</code> removes any legacy entries; <code>track</code> runs the
purge on every merge so existing stores self-heal.</li>
<li>Added <code>funded-issues import-algora-board</code>, an offline parser for a locally
saved Algora organization bounty-board page. It extracts the funder-stated
USD amount, GitHub issue reference, posting age, and declared claim count
per bounty, and can merge the scored records into a tracker store. No
network access is performed.</li>
<li>Added read-only competition and payout-vs-effort scoring signals plus the
<code>funded-issues competition</code> and <code>funded-issues payout-effort</code> batch
commands, all derived from public metadata observations with no claims,
comments, or maintainer contact.</li>
<li>Added an offline owner-level <code>source_noise</code> heuristic and
<code>funded-issues apply-recheck</code>, a local-file-only command that transitions
tracker entries to closed / stale / active from recheck observations.</li>
<li>Added .NET/NuGet/C# and xUnit fixture coverage for <code>dotnet restore</code>,
<code>dotnet build</code>, and <code>dotnet test</code> failure modes, growing the public CI
fixture zoo to 153 cases.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">0.1.1 - 2026-06-12</h2><a id="user-content-011---2026-06-12" class="anchor" aria-label="Permalink: 0.1.1 - 2026-06-12" href="#011---2026-06-12"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><code>ci explain</code> now ends text and Markdown reports with a <code>Guide:</code> link to the
matching getpatchrail.com <code>/fix</code> remediation page; unknown or unpublished
failure classes fall back to the <code>/fix</code> index without a network call.</li>
<li>Added <code>funded-issues fresh</code>, a local read-only radar over the tracker store
that surfaces recently posted or recently labeled funded issues for fast
solver-side triage.</li>
<li>Added <code>pre_commit_hook_failure</code> CI classification so pre-commit hook output is
recognized directly while the CLI still avoids linking to a missing <code>/fix</code>
page until that guide exists.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">0.1.0 - 2026-06-02</h2><a id="user-content-010---2026-06-02" class="anchor" aria-label="Permalink: 0.1.0 - 2026-06-02" href="#010---2026-06-02"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Initial public CI Janitor snapshot.</li>
<li>Added <code>patchrail ci explain</code> and <code>patchrail ci classify</code>.</li>
<li>Added local Markdown, JSON, and text reports.</li>
<li>Added Apache-2.0 license and safety/ethics documentation.</li>
<li>Added fixture-backed tests, local benchmark command, and GitHub Actions CI.</li>
<li>Expanded the initial CI fixture zoo to 101 sanitized synthetic examples across
Python, Node, TypeScript, Go, Rust, and GitHub Actions failure modes.</li>
<li>Added a read-only GitHub Actions triage artifact workflow.</li>
<li>Added the experimental local Agent Control Plane queue with SQLite-backed
work items, approval states, audit export, CI result import, and proposal
records.</li>
<li>Added the experimental read-only <code>funded-issues</code> CLI over local metadata,
with safe-only filtering and explicit anti-abuse blocked actions.</li>
<li>Added permission-only adopter reporting and a public metrics tracker for
pilot outcomes, adoption signals, and open-source program evidence gaps.</li>
<li>Added release-prep evidence docs, package smoke checks, and manual publish
gates. Release tags, PyPI publishing, GitHub Releases, and public
announcements remain maintainer actions.</li>
</ul>
</article></div><div class="d-none"></div></section></div></div></div> </div> <!-- --> </div></div></div></div></div></div><div class="ScrollMarksContainer-module__scrollMarksContainer__Eu7uU" id="find-result-marks-container"></div><div class="d-none"></div><div class="d-none"></div></div> <!-- --> <!-- --> </div>
</react-app>




  </div>

</turbo-frame>

    </main>
  </div>

  </div>

          <footer class="footer f6 color-fg-muted color-border-subtle tmp-pt-7 tmp-pb-6 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://github.community/" 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 code to clipboard" 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 code to clipboard" 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>

