Skip to content
Merged
Show file tree
Hide file tree
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
97 changes: 97 additions & 0 deletions .github/REPO_HEALTH_RUNBOOK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Repo Health workflow verification

`Repo Health` is intentionally base-controlled. Its `pull_request_target` trigger supplies the
workflow definition from the target branch, and every checkout keeps the trusted base revision.
The PR head is fetched only as Git data. Never check out or execute PR-head code in that workflow.

## Evidence levels

- **Shadow / non-authoritative:** `Repo Health Shadow (Non-Authoritative)` runs proposed scanners,
reporter script bodies, and the reporter helper from the PR head under `pull_request`, a
read-only token, no persisted checkout credentials, and fake Octokit. It can prove that proposed
code compiles, preserves hostile text, and propagates API failures, but it cannot prove the
elevated production workflow has picked up the merged implementation.
- **Post-merge / authoritative:** only a disposable PR opened after the change reaches `dev` and
observed through `Repo Health` proves the base-controlled writer now creates and cleans up its
marker comment.

Do not weaken a scanner, add an exclusion, or change a finding merely to make the base-controlled
check on the implementation PR green.

## Authoritative post-merge canary

Run this only after the workflow/helper change is on `dev`. It creates a disposable branch and PR
whose filename contains paired backticks, a bare `${`, an apostrophe, and a double quote. The
filename is data; do not execute it. Multiline transport coverage belongs in scanner diagnostic
messages, because the leakage scanner consumes Git's line-delimited `--name-only` output.

```bash
git fetch origin dev
git switch --create canary/repo-health-$(date +%s) origin/dev

node --input-type=module <<'NODE'
import { mkdirSync, writeFileSync } from 'node:fs';
const path = '.squad/canary-`paired`-${-apostrophe-\'-"double quote".md';
mkdirSync('.squad', { recursive: true });
writeFileSync(path, 'repo-health post-merge canary\n');
NODE

CANARY_PATH=$(node --input-type=module -e \
'process.stdout.write(".squad/canary-`paired`-${-apostrophe-'\''-\"double quote\".md")')
git add -- "$CANARY_PATH"
git commit -m 'test: repo-health post-merge canary'
git push -u origin HEAD
PR_URL=$(gh pr create --base dev --title 'test: repo-health post-merge canary' \
--body 'Disposable authoritative canary; do not merge.')
PR_NUMBER=${PR_URL##*/}
```

Wait for `Repo Health / Squad File Leakage`, then verify exactly one authoritative marker and the
exact hostile filename:

```bash
EXPECTED=$(node --input-type=module -e \
'process.stdout.write(".squad/canary-`paired`-${-apostrophe-'\''-\"double quote\".md")')

gh api --paginate --slurp "repos/bradygaster/squad/issues/$PR_NUMBER/comments" \
> canary-comments.json
node --input-type=module - "$EXPECTED" <<'NODE'
import { readFileSync } from 'node:fs';
const expected = process.argv[2];
const comments = JSON.parse(readFileSync('canary-comments.json', 'utf8')).flat();
const marked = comments.filter(({ body = '' }) =>
body.includes('<!-- squad-repo-health-leakage -->'));
if (marked.length !== 1) throw new Error(`expected one marker comment, found ${marked.length}`);
if (!marked[0].body.includes(expected)) throw new Error('hostile filename was not preserved exactly');
if (!marked[0].body.includes('Authoritative evidence')) {
throw new Error('comment was not labeled authoritative');
}
NODE
rm canary-comments.json
```

Delete the file in the same PR, push, wait for the rerun, and prove stale cleanup:

```bash
git rm -- "$CANARY_PATH"
git commit -m 'test: clean up repo-health post-merge canary'
git push

# After Repo Health / Squad File Leakage completes:
gh api --paginate --slurp "repos/bradygaster/squad/issues/$PR_NUMBER/comments" \
> canary-comments.json
node --input-type=module <<'NODE'
import { readFileSync } from 'node:fs';
const comments = JSON.parse(readFileSync('canary-comments.json', 'utf8')).flat();
const marked = comments.filter(({ body = '' }) =>
body.includes('<!-- squad-repo-health-leakage -->'));
if (marked.length !== 0) throw new Error(`stale marker remains: ${marked.length}`);
NODE
rm canary-comments.json
gh pr close "$PR_NUMBER" --delete-branch
git switch dev
```

Record the PR URL and both successful `Repo Health` run URLs in the implementing PR or issue.
This post-merge canary is the only authoritative evidence for a repo-health workflow/reporter
change; the pre-merge shadow remains intentionally non-authoritative.
73 changes: 73 additions & 0 deletions .github/workflows/squad-repo-health-shadow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Repo Health Shadow (Non-Authoritative)

on:
pull_request:
branches: [dev]
types: [opened, synchronize, reopened]
paths:
- '.github/workflows/squad-repo-health.yml'
- '.github/workflows/squad-repo-health-shadow.yml'
- 'scripts/architectural-review.mjs'
- 'scripts/check-squad-leakage.mjs'
- 'scripts/repo-health-comment.mjs'
- 'scripts/security-review.mjs'
- 'test/scripts/repo-health-comment-transport.test.ts'

# This workflow intentionally runs the PR-head implementation with a read-only token.
# Its scanner output and fake-Octokit reporter exercise are shadow evidence only.
# The pull_request_target workflow remains the authoritative, base-controlled writer.
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
shadow:
name: PR-head scanner/reporter shadow (non-authoritative)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7
with:
fetch-depth: 0
persist-credentials: false

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 #v6
with:
node-version: '22'
cache: npm

- name: Run PR-head scanners as shadow evidence
shell: bash
run: |
set -euo pipefail
git fetch --no-tags origin "${{ github.event.pull_request.base.sha }}"
{
echo '# Repo Health PR-head Shadow'
echo
echo '> **NON-AUTHORITATIVE:** These scanners came from the PR head and have no write token.'
printf '%s\n' "> Only a post-merge canary through \`Repo Health\` is authoritative for workflow/reporter changes."
echo
echo '## Squad leakage'
echo '```text'
node scripts/check-squad-leakage.mjs "${{ github.event.pull_request.base.sha }}" HEAD
echo '```'
echo
echo '## Architectural review'
echo '```text'
node scripts/architectural-review.mjs "${{ github.event.pull_request.base.sha }}" HEAD
echo '```'
echo
echo '## Security review'
echo '```text'
node scripts/security-review.mjs "${{ github.event.pull_request.base.sha }}" HEAD
echo '```'
} >> "$GITHUB_STEP_SUMMARY"

- name: Install test dependencies without lifecycle scripts
run: npm ci --ignore-scripts

- name: Exercise real reporter scripts with fake Octokit
run: npx --no-install vitest run test/scripts/repo-health-comment-transport.test.ts
6 changes: 6 additions & 0 deletions scripts/repo-health-comment.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const JOBS = {
return [
'## ⚠️ Squad File Leakage Detected',
'',
'> **Authoritative evidence:** base-controlled `pull_request_target` reporter.',
'',
'The following `.squad/` files were modified in this PR:',
'',
fileList,
Expand Down Expand Up @@ -51,6 +53,8 @@ const JOBS = {
return [
'## 🏗️ Architectural Review',
'',
'> **Authoritative evidence:** base-controlled `pull_request_target` reporter.',
'',
parsed.summary,
'',
'| Severity | Category | Finding | Files |',
Expand Down Expand Up @@ -83,6 +87,8 @@ const JOBS = {
return [
'## 🔒 Security Review',
'',
'> **Authoritative evidence:** base-controlled `pull_request_target` reporter.',
'',
parsed.summary,
'',
'| Severity | Category | Finding | Location |',
Expand Down
Loading
Loading