Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions spec/audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,17 @@
"has_wiki", "has_projects", "allow_merge_commit", "allow_squash_merge",
"allow_rebase_merge", "allow_auto_merge", "allow_update_branch", "delete_branch_on_merge",
]
RULESET_SUBSET = ["name", "target", "enforcement", "bypass_actors", "conditions", "rules"]
# Phrases in a registry driftNote that assert work still outstanding. Deliberately specific: a note
# recording a permanent deviation ("no get-version-task; relies on validate-task") must not match.
# The bypass_actors field is deliberately absent from this list.
# Who may bypass a ruleset is a per-repository human decision taken in the UI.
# The configure.sh script in repo-config treats it that way, since apply writes the live list back unchanged and check reports it without asserting.
# Comparing it here would contradict that, and did.
# Once the payloads stopped declaring a bypass list, every repo whose live ruleset still had one reported a ruleset DEFECT.
# That was a field the fleet config had deliberately stopped managing.
# Two tools comparing one field under opposite policies is the defect, rather than the field's value.
RULESET_SUBSET = ["name", "target", "enforcement", "conditions", "rules"]
# Phrases in a registry driftNote that assert work is still outstanding.
# Deliberately specific, so a note recording a permanent deviation must not match.
# An example of one that must not match is a note reading that there is no get-version-task and validate-task is relied on instead.
PENDING_MARKERS = ["pending", "not yet", "owed", "todo", "still", "behind", "missing", "absent"]


Expand Down Expand Up @@ -102,8 +110,6 @@ def normalize_ruleset(payload):
sub = {k: payload.get(k) for k in RULESET_SUBSET}
if isinstance(sub.get("rules"), list):
sub["rules"] = sorted(sub["rules"], key=lambda r: json.dumps(r, sort_keys=True))
if isinstance(sub.get("bypass_actors"), list):
sub["bypass_actors"] = sorted(sub["bypass_actors"], key=lambda a: (str(a.get("actor_type")), str(a.get("actor_id"))))
return json.dumps(sub, sort_keys=True)


Expand Down
Loading