From 6c4be80bf3ce316482e0ba4e79af8300c47e6e89 Mon Sep 17 00:00:00 2001
From: Nathan Heaps
Date: Mon, 27 Jul 2026 13:10:19 -0400
Subject: [PATCH 1/2] fix(apply-repo-settings): normalize bypass_actors order
before diffing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
jq -S only sorts object keys, not array element order. GitHub doesn't
guarantee bypass_actors[] comes back in the same order settings.yml
declares them, so the ruleset drift check flagged a permanent false
"needs update" whenever the live and desired bypass_actors sets were
identical but differently ordered — observed identically across
require-pr, require-1-review, and require-codeowner-review on
nsheaps/greasemonkey-scripts (workflow run 30285386587), traced back
from nsheaps/.github#103/#45.
Sort bypass_actors by (actor_type, actor_id) on both sides before the
jq -S comparison so ordering differences no longer register as drift.
Verified against the exact reported scenario (swapped actor_id order)
and against a genuine-gap case (missing actor) to confirm real drift
is still detected.
Co-Authored-By: Claude Code (~/src/nsheaps/github-actions)
---
.github/actions/apply-repo-settings/action.sh | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/.github/actions/apply-repo-settings/action.sh b/.github/actions/apply-repo-settings/action.sh
index 52f778d..09f1990 100755
--- a/.github/actions/apply-repo-settings/action.sh
+++ b/.github/actions/apply-repo-settings/action.sh
@@ -161,11 +161,21 @@ apply_rulesets() {
CREATED+=("$name")
else
# Compare current vs desired to decide if PUT is needed.
+ #
+ # `jq -S` only sorts object KEYS — it leaves array ELEMENT ORDER alone.
+ # GitHub doesn't guarantee bypass_actors[] comes back in the same order
+ # settings.yml declares them in, so a plain `-S` comparison flags a
+ # permanent false "needs update" for rulesets whose actual bypass_actors
+ # set is identical but differently ordered. Sort bypass_actors by a
+ # stable key (actor_type, actor_id) on both sides before the `-S`
+ # comparison so ordering differences don't register as drift.
+ local ruleset_filter='{name, target, enforcement, conditions, rules,
+ bypass_actors: ((.bypass_actors // []) | sort_by(.actor_type, .actor_id))}'
local current_norm desired_norm
current_norm="$(gh api "/repos/${OWNER}/${REPO}/rulesets/${existing_id}" \
- --jq '{name, target, enforcement, conditions, rules, bypass_actors}' \
+ --jq "$ruleset_filter" \
| jq -S '.')"
- desired_norm="$(echo "$body" | jq -S '{name, target, enforcement, conditions, rules, bypass_actors}')"
+ desired_norm="$(echo "$body" | jq -S "$ruleset_filter")"
if [[ "$current_norm" == "$desired_norm" ]]; then
info "unchanged: $name (id=$existing_id)"
UNCHANGED+=("$name")
From c2bdc80549e04642cd8bce5fc984bf4f0251689f Mon Sep 17 00:00:00 2001
From: nsheaps-oura <300890611+nsheaps-oura@users.noreply.github.com>
Date: Mon, 27 Jul 2026 17:11:08 +0000
Subject: [PATCH 2/2] chore: `mise format`
Triggered by: de8bdc42506460a3beb684fd555476361f8f2a97
Workflow run: https://github.com/nsheaps/github-actions/actions/runs/30288094498
---
.../1/1771874092/documentation/REPORT.md | 16 ++++++++--------
LICENSE.md | 2 +-
pages/index.html | 3 +--
3 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/.claude/pr-reviews/nsheaps/github-actions/1/1771874092/documentation/REPORT.md b/.claude/pr-reviews/nsheaps/github-actions/1/1771874092/documentation/REPORT.md
index 47964ad..65c5390 100644
--- a/.claude/pr-reviews/nsheaps/github-actions/1/1771874092/documentation/REPORT.md
+++ b/.claude/pr-reviews/nsheaps/github-actions/1/1771874092/documentation/REPORT.md
@@ -100,15 +100,15 @@ This PR delivers strong, well-structured documentation that significantly exceed
### Summary of Deductions
-| Category | Deduction | Reason |
+| Category | Deduction | Reason |
| ---------------------------------- | --------- | --------------------------------------------------------------------- | --- | -------------------------------- |
-| Missing troubleshooting/error docs | -5 | No guidance on common failure modes |
-| Missing prerequisites | -2 | No runner/dependency requirements noted |
-| Incomplete edge-case docs | -4 | maxdepth 2 limit, root-path sync naming, never-deletes implications |
-| env-vars behavior mismatch | -2 | README implies compose-level injection, script does GITHUB_ENV export |
-| auth-type values underdocumented | -2 | No explanation of what each auth type requires |
-| Missing function docstrings | -2 | `discover_compose_files` and `export_env_vars` lack docstrings |
-| Minor inline comment gaps | -1 | ` | | true`on curl,`sort -z` rationale |
+| Missing troubleshooting/error docs | -5 | No guidance on common failure modes |
+| Missing prerequisites | -2 | No runner/dependency requirements noted |
+| Incomplete edge-case docs | -4 | maxdepth 2 limit, root-path sync naming, never-deletes implications |
+| env-vars behavior mismatch | -2 | README implies compose-level injection, script does GITHUB_ENV export |
+| auth-type values underdocumented | -2 | No explanation of what each auth type requires |
+| Missing function docstrings | -2 | `discover_compose_files` and `export_env_vars` lack docstrings |
+| Minor inline comment gaps | -1 | ` | | true`on curl,`sort -z` rationale |
## References
diff --git a/LICENSE.md b/LICENSE.md
index e70157b..c3fc5da 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -11,7 +11,7 @@ Copyright (c) 2026 Nathan Heaps. All rights reserved.
> (https://polyformproject.org/licenses/internal-use/1.0.0), which is
> purpose-built for "use the software for internal business operations, do
> not distribute it." The one substantive adaptation is that PolyForm grants
-> rights to *"you and your company"* (whoever accepts the license), whereas
+> rights to _"you and your company"_ (whoever accepts the license), whereas
> this license grants them to a **single, specifically named licensee**
> (Oura, defined below). That is a real difference: the licensor here is not
> a generic member of the licensee's organization, so the "permitted
diff --git a/pages/index.html b/pages/index.html
index 820fe74..caec1b6 100644
--- a/pages/index.html
+++ b/pages/index.html
@@ -319,8 +319,7 @@ Detailed setup walkthrough
cp pages/index.html docs/index.html
-# Settings → Pages → Source: GitHub Actions (or branch /docs)
+# Settings → Pages → Source: GitHub Actions (or branch /docs)
Then use https://<your-org>.github.io/<repo>/ as the redirect. Any
other HTTPS static host (Vercel, Netlify, etc.) works equally well.