Add audit-freeze CI gate and ENGAGEMENT.md template (#158) - #183
Merged
truthixify merged 5 commits intoAug 31, 2026
Merged
Conversation
…#158) Scoped subset per maintainer's comment on wraith-protocol#158: the workflow, the ENGAGEMENT.md template, and (separately, via a throwaway PR) a demonstration that the gate fires. Firm selection, the signed SOW, and README.md/AUDIT_FIRMS.md/MAINNET_READINESS.md remain untouched, as those are explicitly the maintainer's to fill in. - .github/workflows/audit-freeze.yml: runs on every PR, checks out the PR's base ref (not the default merge ref) so the gate script itself cannot be modified by the PR it is judging. - scripts/audit-freeze/{parse,glob,decide,check}.ts: dependency-free front-matter parser, glob matcher, pass/fail decision logic, and a CLI that fetches PR metadata, changed files, and ENGAGEMENT.md's content (from the base SHA) via the GitHub REST API. - audit-prep/ENGAGEMENT.md: template with the front-matter shape and section structure the gate expects, freeze_until defaulted to the literal "TBD" placeholder (inactive) until a real SOW is signed. Security design (two independent layers, per the maintainer's ask to choose one and say which): (1) primary -- the workflow checks out the PR's base ref, and check.ts separately fetches ENGAGEMENT.md's content from that same base SHA via the API, so a PR cannot alter the freeze parameters it is judged against; (2) secondary -- ENGAGEMENT.md is always treated as a frozen path in its own right whenever a freeze is active, regardless of freeze_paths contents. Full writeup in scripts/audit-freeze/README.md. Tests: 26 passing -- unit tests for parse/glob/decide (no network), plus a subprocess end-to-end suite that runs check.ts against a local mock GitHub API server, covering blocked/approved-label/no-freeze/ missing-file/self-protection cases.
|
@Jerryvic911 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
added 2 commits
August 30, 2026 14:34
Sparse-checkout in non-cone mode did not reliably include the full scripts/audit-freeze directory contents, causing check.ts to be missing at runtime (ERR_MODULE_NOT_FOUND) on a real PR run. A full checkout is simpler and removes this failure mode; sparse-checkout was only ever a minor optimization, not load-bearing.
added 2 commits
August 30, 2026 14:53
The freeze was temporarily activated to demonstrate the audit-freeze gate firing on a real PR (see linked demo PR in wraith-protocol#158). Restoring the inactive TBD placeholder now that the demonstration is complete.
The base-ref checkout is correct and intentional (see security note), but means the very first PR that introduces scripts/audit-freeze/ will find nothing there, since the system did not exist at that point in history. That is not a security gap -- if the system does not exist on base, there is nothing to enforce or bypass -- but the workflow crashed instead of recognizing that. Now it checks whether check.ts exists on the checked-out base ref first, and passes cleanly with an explanatory message if not.
Contributor
|
Merged @Jerryvic911, and you closed the hole I flagged rather than just noting it. Reading ENGAGEMENT.md from the base ref and treating it as an always-frozen path is belt and braces, which is right for a control whose whole job is to be un-bypassable. You also left MAINNET_READINESS.md alone as asked and kept the coordinator fields as placeholders for me. Exactly the split I described. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes (partially) #158
Closes #158
Scope note
Per the maintainer's scoping comment on #158, this PR covers only the
contributor-facing subset of the issue:
.github/workflows/audit-freeze.ymlaudit-prep/ENGAGEMENT.mdas a template (placeholders, not a signed SOW)audit-prep/README.md,audit-prep/AUDIT_FIRMS.md, andstellar/MAINNET_READINESS.mdare intentionally untouched — firmselection, the signed SOW, and the real coordinator/technical-contact
names are the maintainer's to fill in, and no row in
MAINNET_READINESS.mdshould flip until a real engagement is signed.Security design (maintainer asked to pick one approach and say which)
Two independent layers, not just one:
(
github.event.pull_request.base.sha), not the default PR-merge ref —so the gate script itself (
scripts/audit-freeze/*.ts) cannot bemodified by the PR it's judging.
check.tsseparately fetchesENGAGEMENT.md's content from that same base SHA via the GitHubContents API, so a PR's edits to that file are simply invisible to the
check.
ENGAGEMENT.mdis always treated asa frozen path in its own right whenever a freeze is active, regardless
of what
freeze_pathslists — so even if (1) ever regressed, editingthe file still requires the
audit-approvedlabel.Full writeup in
scripts/audit-freeze/README.md.Testing
26 tests passing:
(
parse.test.ts,glob.test.ts,decide.test.ts) — no network.check.e2e.test.ts) that runs the realcheck.tsCLI against a local mock GitHub API server, covering: ablocked PR, the
audit-approvedlabel override, no active freeze, amissing
ENGAGEMENT.mdat the base ref, and the self-protection case.Demonstration that the gate fires
Update: fixes found via live demonstration
While putting together the required demonstration that the gate fires
(see below), two real bugs surfaced that only a live PR run — not local
mock tests — could catch:
sparse-checkoutin non-cone mode silently droppedscripts/audit-freeze/, causingERR_MODULE_NOT_FOUNDat runtime.Fixed by dropping
sparse-checkoutentirely in favor of a plain fullcheckout at the base ref (sparse-checkout was only ever a minor
optimization, not load-bearing).
that introduces the audit-freeze system itself — since the base-ref
checkout (by design) finds nothing at
scripts/audit-freeze/check.tson
develop, because it doesn't exist there yet. Fixed by having theworkflow check whether
check.tsexists on the checked-out base reffirst, and pass with an explanatory message if not. This isn't a
security gap: if the system doesn't exist on base, there's nothing to
enforce or bypass.
Both fixes are now included in this PR and verified against a real PR
run (see the demonstration below).
Demonstration that the gate fires
Jerryvic911#1
That PR (base: this branch,
issue-158-audit-freeze) temporarilyactivated the freeze and touched
stellar/stealth-announcer/README.md(an in-scope frozen path):
audit-approvedlabel:Audit Freeze Gatefailed, asexpected.
audit-approvedlabel: the same check passed,confirming the override path works.
The freeze activation was reverted afterward (see the
revert:commit)—
audit-prep/ENGAGEMENT.mdis back to the inactive"TBD"placeholderon this branch.