diff --git a/.github/workflows/agent-shield.yml b/.github/workflows/agent-shield.yml index d627ea4c..4cf7bb7d 100644 --- a/.github/workflows/agent-shield.yml +++ b/.github/workflows/agent-shield.yml @@ -30,4 +30,4 @@ permissions: jobs: agent-shield: - uses: petry-projects/.github/.github/workflows/agent-shield-reusable.yml@v2 + uses: petry-projects/.github/.github/workflows/agent-shield-reusable.yml@agent-shield/stable diff --git a/.github/workflows/apply-repo-settings.yml b/.github/workflows/apply-repo-settings.yml index c3a3ed19..a40a5a4e 100644 --- a/.github/workflows/apply-repo-settings.yml +++ b/.github/workflows/apply-repo-settings.yml @@ -2,10 +2,10 @@ # Standard: petry-projects/.github/standards/push-protection.md#required-repo-level-settings # # Applies repository-level security settings (secret_scanning_ai_detection, etc.) -# via scripts/apply-repo-settings.sh on every push to main and on a weekly -# schedule (Mon 03:00 UTC) so that security_and_analysis settings documented -# in .github/settings.yml stay in effect and drift is caught between compliance -# audits. Also triggerable manually for out-of-band remediation. +# via scripts/apply-repo-settings.sh on path-filtered pushes to main, on a +# weekly schedule (Mondays 06:00 UTC), and via manual dispatch. This ensures +# security_and_analysis settings documented in .github/settings.yml stay in +# effect and prevents drift over time. # # Token: GH_PAT_WORKFLOWS (classic PAT with repo scope). # `administration` is not a valid GITHUB_TOKEN scope in Actions; and the @@ -20,18 +20,12 @@ on: paths: - .github/settings.yml - scripts/apply-repo-settings.sh - - .github/workflows/apply-repo-settings.yml schedule: - # Reinforce settings weekly (Mon 03:00 UTC) so drift is caught between compliance audits. - - cron: '0 3 * * 1' + - cron: '0 6 * * 1' # Weekly Monday 06:00 UTC — prevents settings drift workflow_dispatch: permissions: {} -concurrency: - group: apply-repo-settings - cancel-in-progress: false - jobs: apply: name: Apply security_and_analysis settings diff --git a/.github/workflows/ci-failure-analyst.yml b/.github/workflows/ci-failure-analyst.yml index 3ab2f095..bb0fd3c1 100644 --- a/.github/workflows/ci-failure-analyst.yml +++ b/.github/workflows/ci-failure-analyst.yml @@ -41,6 +41,6 @@ jobs: if: >- github.event.check_run.conclusion == 'failure' && !startsWith(github.event.check_run.name, 'CI Failure Analyst') - uses: petry-projects/.github-private/.github/workflows/ci-failure-analyst-reusable.yml@ac05d653e05c038bf5f82b1e9612d5015399a675 # main + uses: petry-projects/.github-private/.github/workflows/ci-failure-analyst-reusable.yml@121bee881bd13715706d30230b2d5a8d2d78b0b1 # main secrets: CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 497f77c2..c1c5ef2f 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -35,5 +35,5 @@ jobs: permissions: contents: read pull-requests: read - uses: petry-projects/.github/.github/workflows/dependabot-automerge-reusable.yml@v2 + uses: petry-projects/.github/.github/workflows/dependabot-automerge-reusable.yml@dependabot-automerge/stable secrets: inherit diff --git a/.github/workflows/dependency-audit.yml b/.github/workflows/dependency-audit.yml index 72df1d0d..c1af742e 100644 --- a/.github/workflows/dependency-audit.yml +++ b/.github/workflows/dependency-audit.yml @@ -30,4 +30,4 @@ permissions: jobs: dependency-audit: - uses: petry-projects/.github/.github/workflows/dependency-audit-reusable.yml@v2 + uses: petry-projects/.github/.github/workflows/dependency-audit-reusable.yml@dependency-audit/stable diff --git a/.github/workflows/feature-ideation.yml b/.github/workflows/feature-ideation.yml index 3e4e9db1..0334de5f 100644 --- a/.github/workflows/feature-ideation.yml +++ b/.github/workflows/feature-ideation.yml @@ -88,7 +88,7 @@ jobs: discussions: write id-token: write actions: read - uses: petry-projects/.github/.github/workflows/feature-ideation-reusable.yml@cc05a74683f8e3564592878e417bb20f8013f16f # v1 + uses: petry-projects/.github/.github/workflows/feature-ideation-reusable.yml@ce8a8c328b21feb26c7bb9ef81ffb26354e9a4da # v1 with: # === CUSTOMISE THIS PER REPO — the only required edit === # Replace this paragraph with a 3-5 sentence description of your project, diff --git a/.github/workflows/pr-review-mention.yml b/.github/workflows/pr-review-mention.yml index d7cf51d1..2bc54fb0 100644 --- a/.github/workflows/pr-review-mention.yml +++ b/.github/workflows/pr-review-mention.yml @@ -41,3 +41,4 @@ jobs: statuses: read uses: petry-projects/.github/.github/workflows/pr-review-mention-reusable.yml@v2 secrets: inherit + diff --git a/.github/workflows/pr-review.yml b/.github/workflows/pr-review.yml index 96093f32..901ce637 100644 --- a/.github/workflows/pr-review.yml +++ b/.github/workflows/pr-review.yml @@ -1,62 +1,28 @@ name: PR Review Agent -# Thin caller for the org PR Review agent (petry-projects/.github-private), -# pinned to the known-good `pr-review/stable` channel. Adopted from the validated -# `.github-private/pr-review-trigger.yml` template (#536 consumer fan-out). -# -# - Version selection is the `pr-review/stable` tag. The `uses:` line is pinned -# to the tag's current commit SHA and must be bumped when the tag is promoted. -# `agent_ref` tracks the mutable tag so agent scripts use the promoted version. -# - `agent_ref: pr-review/stable` pins the agent's own scripts to the same -# channel (#506), so the review logic AND scripts run the known-good version. -# - Secrets are passed explicitly to the reusable workflow. -# `DON_PETRY_BOT_GH_PAT_CLASSIC` is a classic PAT — required for approvals since -# fine-grained PATs cannot `addPullRequestReview`. - on: - check_suite: - types: [completed] - pull_request_review: - types: [submitted, dismissed] pull_request: - types: [opened, ready_for_review, reopened, synchronize] + types: [opened, synchronize, reopened] + pull_request_review_comment: + types: [created] + issue_comment: + types: [created] workflow_dispatch: inputs: - pr_url: - description: "Optional: review a single PR URL instead of enumerating" - required: false - type: string - dry_run: - description: "If true, never submit reviews or comments" + pr_numbers: + description: "PR numbers to review (comma-separated)" required: false - default: "false" - type: string - force_review: - description: "If true, bypass idempotency and re-review at the same head SHA" - required: false - default: "false" - type: string - repository_dispatch: - types: [pr-review-mention] permissions: {} +concurrency: + group: pr-review-${{ github.event.pull_request.number || github.event.issue.number || github.sha }} + cancel-in-progress: true + jobs: - review: - permissions: - contents: read - pull-requests: write - checks: read - uses: petry-projects/.github-private/.github/workflows/pr-review.yml@ded84ce4820dce379f177f9992beb74483f6d6b4 # pr-review/stable (v1.7.0) - with: - agent_ref: pr-review/stable - pr_url: ${{ inputs.pr_url || '' }} - dry_run: ${{ inputs.dry_run || '' }} - force_review: ${{ inputs.force_review || '' }} + pr-review: + uses: petry-projects/.github-private/.github/workflows/pr-review-reusable.yml@ceab48a1c64d1e06a87d41ea5cf590c8e6a780bf secrets: CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - DON_PETRY_BOT_GH_PAT: ${{ secrets.DON_PETRY_BOT_GH_PAT }} - DON_PETRY_BOT_GH_PAT_CLASSIC: ${{ secrets.DON_PETRY_BOT_GH_PAT_CLASSIC }} - GH_PAT: ${{ secrets.GH_PAT }} diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 7760c6ec..7d92b2eb 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -23,4 +23,4 @@ jobs: fetch-depth: 0 - name: SonarCloud Scan if: ${{ env.SONAR_TOKEN != '' }} - uses: SonarSource/sonarqube-scan-action@713881670b6b3676cda39549040e2d88c70d582e # v8.2.0 + uses: SonarSource/sonarqube-scan-action@7006c4492b2e0ee0f816d36501671557c97f5995 # v8.1.0 diff --git a/.gitleaksignore b/.gitleaksignore index 15a64718..d7eadf73 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -36,12 +36,9 @@ e8cc0956c901e454aed61e7b10857e6a1a412881:_bmad/_config/files-manifest.csv:generi e8cc0956c901e454aed61e7b10857e6a1a412881:_bmad/_config/files-manifest.csv:generic-api-key:409 e8cc0956c901e454aed61e7b10857e6a1a412881:_bmad/_config/files-manifest.csv:generic-api-key:433 -# Commit aec934f: _bmad/_config/files-manifest.csv (lines 281, 282, 284, 300, -# 409, 433) — same false positives as e8cc0956, same justification: SHA256 -# content checksums in a CSV manifest, not API keys. Alternate commit refs for -# the same false positives (line numbering may change across different repo -# states; these fingerprints ensure consistency across gitleaks runs with -# varying commit representations). +# Commit aec934f9: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files) appearing in a later commit +# that re-introduced the same content. Same false-positive rationale applies. aec934f92f4174b89944ee57a3d5cf68737f71c9:_bmad/_config/files-manifest.csv:generic-api-key:281 aec934f92f4174b89944ee57a3d5cf68737f71c9:_bmad/_config/files-manifest.csv:generic-api-key:282 aec934f92f4174b89944ee57a3d5cf68737f71c9:_bmad/_config/files-manifest.csv:generic-api-key:284 @@ -61,16 +58,17 @@ aec934f92f4174b89944ee57a3d5cf68737f71c9:_bmad/_config/files-manifest.csv:generi 45b6a8ef162096dae42b2a8194334f24a6576f69:_bmad/_config/files-manifest.csv:generic-api-key:409 45b6a8ef162096dae42b2a8194334f24a6576f69:_bmad/_config/files-manifest.csv:generic-api-key:433 -# Commits 58a86a1c and 146f8e14: _bmad/_config/files-manifest.csv (lines 281, -# 282, 284, 300, 409, 433) — same false positives as e8cc0956, aec934f, and -# 45b6a8ef: SHA256 content checksums in a CSV manifest, not API keys. These -# are additional commit refs for the same file/lines as the entries above. +# Commit 58a86a1: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. 58a86a1cd7a8f64efbe0139ecb88184ddf10710a:_bmad/_config/files-manifest.csv:generic-api-key:281 58a86a1cd7a8f64efbe0139ecb88184ddf10710a:_bmad/_config/files-manifest.csv:generic-api-key:282 58a86a1cd7a8f64efbe0139ecb88184ddf10710a:_bmad/_config/files-manifest.csv:generic-api-key:284 58a86a1cd7a8f64efbe0139ecb88184ddf10710a:_bmad/_config/files-manifest.csv:generic-api-key:300 58a86a1cd7a8f64efbe0139ecb88184ddf10710a:_bmad/_config/files-manifest.csv:generic-api-key:409 58a86a1cd7a8f64efbe0139ecb88184ddf10710a:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 146f8e14: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. 146f8e140e166da953907450a3e10985772933ea:_bmad/_config/files-manifest.csv:generic-api-key:281 146f8e140e166da953907450a3e10985772933ea:_bmad/_config/files-manifest.csv:generic-api-key:282 146f8e140e166da953907450a3e10985772933ea:_bmad/_config/files-manifest.csv:generic-api-key:284 @@ -78,9 +76,8 @@ aec934f92f4174b89944ee57a3d5cf68737f71c9:_bmad/_config/files-manifest.csv:generi 146f8e140e166da953907450a3e10985772933ea:_bmad/_config/files-manifest.csv:generic-api-key:409 146f8e140e166da953907450a3e10985772933ea:_bmad/_config/files-manifest.csv:generic-api-key:433 -# Commit c5099d1d: _bmad/_config/files-manifest.csv (lines 281, 282, 284, 300, -# 409, 433) — same false positives as e8cc0956, aec934f, 45b6a8ef, 58a86a1c, -# and 146f8e14: SHA256 content checksums in a CSV manifest, not API keys. +# Commit c5099d1d: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. c5099d1dfbc58bd65ddd0e4efd267666260bb3f6:_bmad/_config/files-manifest.csv:generic-api-key:281 c5099d1dfbc58bd65ddd0e4efd267666260bb3f6:_bmad/_config/files-manifest.csv:generic-api-key:282 c5099d1dfbc58bd65ddd0e4efd267666260bb3f6:_bmad/_config/files-manifest.csv:generic-api-key:284 @@ -88,22 +85,26 @@ c5099d1dfbc58bd65ddd0e4efd267666260bb3f6:_bmad/_config/files-manifest.csv:generi c5099d1dfbc58bd65ddd0e4efd267666260bb3f6:_bmad/_config/files-manifest.csv:generic-api-key:409 c5099d1dfbc58bd65ddd0e4efd267666260bb3f6:_bmad/_config/files-manifest.csv:generic-api-key:433 -# Commits 899ea777, 40bd4031, 4c9852dc: same _bmad/_config/files-manifest.csv CSV rows as -# above (SHA256 content checksums of BMAD skill files). Same false-positive rationale. -# These three commits appeared in the full-history scan triggered by PR #309 but were not -# yet suppressed; pattern is identical to the already-reviewed entries above. +# Commit 899ea777: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. 899ea7773683bc45c329b6d5f413c8662c67d6f1:_bmad/_config/files-manifest.csv:generic-api-key:281 899ea7773683bc45c329b6d5f413c8662c67d6f1:_bmad/_config/files-manifest.csv:generic-api-key:282 899ea7773683bc45c329b6d5f413c8662c67d6f1:_bmad/_config/files-manifest.csv:generic-api-key:284 899ea7773683bc45c329b6d5f413c8662c67d6f1:_bmad/_config/files-manifest.csv:generic-api-key:300 899ea7773683bc45c329b6d5f413c8662c67d6f1:_bmad/_config/files-manifest.csv:generic-api-key:409 899ea7773683bc45c329b6d5f413c8662c67d6f1:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 40bd4031: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. 40bd40314d66e26adc09503c098e34e4254a53a9:_bmad/_config/files-manifest.csv:generic-api-key:281 40bd40314d66e26adc09503c098e34e4254a53a9:_bmad/_config/files-manifest.csv:generic-api-key:282 40bd40314d66e26adc09503c098e34e4254a53a9:_bmad/_config/files-manifest.csv:generic-api-key:284 40bd40314d66e26adc09503c098e34e4254a53a9:_bmad/_config/files-manifest.csv:generic-api-key:300 40bd40314d66e26adc09503c098e34e4254a53a9:_bmad/_config/files-manifest.csv:generic-api-key:409 40bd40314d66e26adc09503c098e34e4254a53a9:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 4c9852dc: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. 4c9852dcd788730edfb9aaac3c7cca3a6777df9f:_bmad/_config/files-manifest.csv:generic-api-key:281 4c9852dcd788730edfb9aaac3c7cca3a6777df9f:_bmad/_config/files-manifest.csv:generic-api-key:282 4c9852dcd788730edfb9aaac3c7cca3a6777df9f:_bmad/_config/files-manifest.csv:generic-api-key:284 @@ -111,53 +112,157 @@ c5099d1dfbc58bd65ddd0e4efd267666260bb3f6:_bmad/_config/files-manifest.csv:generi 4c9852dcd788730edfb9aaac3c7cca3a6777df9f:_bmad/_config/files-manifest.csv:generic-api-key:409 4c9852dcd788730edfb9aaac3c7cca3a6777df9f:_bmad/_config/files-manifest.csv:generic-api-key:433 -# Commit 38e9f745: same _bmad/_config/files-manifest.csv CSV rows as above -# (SHA256 content checksums of BMAD skill files). Same false-positive rationale; -# file content checksums in CSV, not API keys. -38e9f74523fb9c79fa465831381c3ce9ac050c29:_bmad/_config/files-manifest.csv:generic-api-key:281 -38e9f74523fb9c79fa465831381c3ce9ac050c29:_bmad/_config/files-manifest.csv:generic-api-key:282 -38e9f74523fb9c79fa465831381c3ce9ac050c29:_bmad/_config/files-manifest.csv:generic-api-key:284 -38e9f74523fb9c79fa465831381c3ce9ac050c29:_bmad/_config/files-manifest.csv:generic-api-key:300 -38e9f74523fb9c79fa465831381c3ce9ac050c29:_bmad/_config/files-manifest.csv:generic-api-key:409 -38e9f74523fb9c79fa465831381c3ce9ac050c29:_bmad/_config/files-manifest.csv:generic-api-key:433 - -# Commit da36d9b3: same _bmad/_config/files-manifest.csv CSV rows as above -# (SHA256 content checksums of BMAD skill files). Same false-positive rationale; -# file content checksums in CSV, not API keys. Earlier commit with same content. -da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:281 -da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:282 -da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:284 -da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:300 -da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:409 -da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:433 - -# Commits 3d0fa154, 38957566, 449c717b, f57f0350: same _bmad/_config/files-manifest.csv CSV rows -# as above (SHA256 content checksums of BMAD skill files). Same false-positive rationale; -# file content checksums in CSV, not API keys. These additional commits appear in the full-history -# scan but were not previously suppressed. Commit f57f0350 is a rebase/merge copy of the -# "chore: add ECC integration, TEA module, and slim CLAUDE.md" change; 3d0fa154 previously had -# only line 433 suppressed — lines 281, 282, 284, 300, and 409 are added here. +# Commit 3d0fa154: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. 3d0fa154391350f48912593a0a9cd5671dba4ca8:_bmad/_config/files-manifest.csv:generic-api-key:281 3d0fa154391350f48912593a0a9cd5671dba4ca8:_bmad/_config/files-manifest.csv:generic-api-key:282 3d0fa154391350f48912593a0a9cd5671dba4ca8:_bmad/_config/files-manifest.csv:generic-api-key:284 3d0fa154391350f48912593a0a9cd5671dba4ca8:_bmad/_config/files-manifest.csv:generic-api-key:300 3d0fa154391350f48912593a0a9cd5671dba4ca8:_bmad/_config/files-manifest.csv:generic-api-key:409 3d0fa154391350f48912593a0a9cd5671dba4ca8:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 38957566: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. 38957566a56f3731d5bd2bc9dcb5e00131e82d74:_bmad/_config/files-manifest.csv:generic-api-key:281 38957566a56f3731d5bd2bc9dcb5e00131e82d74:_bmad/_config/files-manifest.csv:generic-api-key:282 38957566a56f3731d5bd2bc9dcb5e00131e82d74:_bmad/_config/files-manifest.csv:generic-api-key:284 38957566a56f3731d5bd2bc9dcb5e00131e82d74:_bmad/_config/files-manifest.csv:generic-api-key:300 38957566a56f3731d5bd2bc9dcb5e00131e82d74:_bmad/_config/files-manifest.csv:generic-api-key:409 38957566a56f3731d5bd2bc9dcb5e00131e82d74:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 449c717b: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. 449c717b8353cba9820c2cbd1413dfd83b4b2ea5:_bmad/_config/files-manifest.csv:generic-api-key:281 449c717b8353cba9820c2cbd1413dfd83b4b2ea5:_bmad/_config/files-manifest.csv:generic-api-key:282 449c717b8353cba9820c2cbd1413dfd83b4b2ea5:_bmad/_config/files-manifest.csv:generic-api-key:284 449c717b8353cba9820c2cbd1413dfd83b4b2ea5:_bmad/_config/files-manifest.csv:generic-api-key:300 449c717b8353cba9820c2cbd1413dfd83b4b2ea5:_bmad/_config/files-manifest.csv:generic-api-key:409 449c717b8353cba9820c2cbd1413dfd83b4b2ea5:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit da36d9b3: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. +da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:281 +da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:282 +da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:284 +da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:300 +da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:409 +da36d9b36916087f02c4c367ad6107ab7dbdb152:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit bbc895a9: _bmad/_config/files-manifest.csv — this is the initial +# "Install BMad Method v6.2.0" commit (333-line version). Lines 281, 282, 284, +# 300 contain SHA256 content checksums of BMAD skill files (same pattern as +# other suppressed commits). The file has only 333 lines so lines 409/433 do +# not exist here. Not a real credential. +bbc895a93baa10e9fb2848d9fcd32c57b52f0bc7:_bmad/_config/files-manifest.csv:generic-api-key:281 +bbc895a93baa10e9fb2848d9fcd32c57b52f0bc7:_bmad/_config/files-manifest.csv:generic-api-key:282 +bbc895a93baa10e9fb2848d9fcd32c57b52f0bc7:_bmad/_config/files-manifest.csv:generic-api-key:284 +bbc895a93baa10e9fb2848d9fcd32c57b52f0bc7:_bmad/_config/files-manifest.csv:generic-api-key:300 + +# Commit 4cc93b30: same _bmad/_config/files-manifest.csv SHA256 content +# checksums as bbc895a9 (another copy of the initial BMad Method install +# commit at a different tree SHA due to rebase/merge). Same false-positive +# rationale. File has 333 lines. +4cc93b30c661729170913d62e1efac32495a37f4:_bmad/_config/files-manifest.csv:generic-api-key:281 +4cc93b30c661729170913d62e1efac32495a37f4:_bmad/_config/files-manifest.csv:generic-api-key:282 +4cc93b30c661729170913d62e1efac32495a37f4:_bmad/_config/files-manifest.csv:generic-api-key:284 +4cc93b30c661729170913d62e1efac32495a37f4:_bmad/_config/files-manifest.csv:generic-api-key:300 + +# Commit b395845f: same _bmad/_config/files-manifest.csv SHA256 content +# checksums as bbc895a9 (another copy of the initial BMad Method install +# commit at a different tree SHA due to rebase/merge). Same false-positive +# rationale. File has 333 lines. +b395845f46a5b39d97a0f6f1dd5ec63915c25ada:_bmad/_config/files-manifest.csv:generic-api-key:281 +b395845f46a5b39d97a0f6f1dd5ec63915c25ada:_bmad/_config/files-manifest.csv:generic-api-key:282 +b395845f46a5b39d97a0f6f1dd5ec63915c25ada:_bmad/_config/files-manifest.csv:generic-api-key:284 +b395845f46a5b39d97a0f6f1dd5ec63915c25ada:_bmad/_config/files-manifest.csv:generic-api-key:300 + +# Commit f57f0350: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Commit message: +# "chore: add ECC integration, TEA module, and slim CLAUDE.md". +# Same false-positive rationale: high-entropy hex strings are file-content +# checksums, not API keys. f57f0350a41b516a0c37bd87943ed6d67842980c:_bmad/_config/files-manifest.csv:generic-api-key:281 f57f0350a41b516a0c37bd87943ed6d67842980c:_bmad/_config/files-manifest.csv:generic-api-key:282 f57f0350a41b516a0c37bd87943ed6d67842980c:_bmad/_config/files-manifest.csv:generic-api-key:284 f57f0350a41b516a0c37bd87943ed6d67842980c:_bmad/_config/files-manifest.csv:generic-api-key:300 f57f0350a41b516a0c37bd87943ed6d67842980c:_bmad/_config/files-manifest.csv:generic-api-key:409 f57f0350a41b516a0c37bd87943ed6d67842980c:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit edb82932: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. +edb82932580a2ac446db7a79dba0ff3911f62183:_bmad/_config/files-manifest.csv:generic-api-key:281 +edb82932580a2ac446db7a79dba0ff3911f62183:_bmad/_config/files-manifest.csv:generic-api-key:282 +edb82932580a2ac446db7a79dba0ff3911f62183:_bmad/_config/files-manifest.csv:generic-api-key:284 +edb82932580a2ac446db7a79dba0ff3911f62183:_bmad/_config/files-manifest.csv:generic-api-key:300 +edb82932580a2ac446db7a79dba0ff3911f62183:_bmad/_config/files-manifest.csv:generic-api-key:409 +edb82932580a2ac446db7a79dba0ff3911f62183:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 720229a3: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. +720229a321e7c25faba82e19d3a099b9cc5499d6:_bmad/_config/files-manifest.csv:generic-api-key:281 +720229a321e7c25faba82e19d3a099b9cc5499d6:_bmad/_config/files-manifest.csv:generic-api-key:282 +720229a321e7c25faba82e19d3a099b9cc5499d6:_bmad/_config/files-manifest.csv:generic-api-key:284 +720229a321e7c25faba82e19d3a099b9cc5499d6:_bmad/_config/files-manifest.csv:generic-api-key:300 +720229a321e7c25faba82e19d3a099b9cc5499d6:_bmad/_config/files-manifest.csv:generic-api-key:409 +720229a321e7c25faba82e19d3a099b9cc5499d6:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 5a40de92: same _bmad/_config/files-manifest.csv CSV row as above +# (SHA256 content checksum of BMAD skill files). Same false-positive rationale. +5a40de92116169412709f7be5dec3acba0501953:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 7f87a9bb: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. +7f87a9bb29faa938ce55b6375fac0039b08d4573:_bmad/_config/files-manifest.csv:generic-api-key:281 +7f87a9bb29faa938ce55b6375fac0039b08d4573:_bmad/_config/files-manifest.csv:generic-api-key:282 +7f87a9bb29faa938ce55b6375fac0039b08d4573:_bmad/_config/files-manifest.csv:generic-api-key:284 +7f87a9bb29faa938ce55b6375fac0039b08d4573:_bmad/_config/files-manifest.csv:generic-api-key:300 +7f87a9bb29faa938ce55b6375fac0039b08d4573:_bmad/_config/files-manifest.csv:generic-api-key:409 +7f87a9bb29faa938ce55b6375fac0039b08d4573:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 85cb1f5f: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. +85cb1f5ffd6e0ed36ea87f8b2370a6746a5727c0:_bmad/_config/files-manifest.csv:generic-api-key:281 +85cb1f5ffd6e0ed36ea87f8b2370a6746a5727c0:_bmad/_config/files-manifest.csv:generic-api-key:282 +85cb1f5ffd6e0ed36ea87f8b2370a6746a5727c0:_bmad/_config/files-manifest.csv:generic-api-key:284 +85cb1f5ffd6e0ed36ea87f8b2370a6746a5727c0:_bmad/_config/files-manifest.csv:generic-api-key:300 +85cb1f5ffd6e0ed36ea87f8b2370a6746a5727c0:_bmad/_config/files-manifest.csv:generic-api-key:409 +85cb1f5ffd6e0ed36ea87f8b2370a6746a5727c0:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit edf35287: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files), plus a line 681 in +# api-testing-patterns.md containing a test-design pattern with an expired/example +# token. Same false-positive rationale: file-content checksums and test documentation. +edf3528742de7c0bd83dc513c159152353f711ae:_bmad/_config/files-manifest.csv:generic-api-key:281 +edf3528742de7c0bd83dc513c159152353f711ae:_bmad/_config/files-manifest.csv:generic-api-key:282 +edf3528742de7c0bd83dc513c159152353f711ae:_bmad/_config/files-manifest.csv:generic-api-key:284 +edf3528742de7c0bd83dc513c159152353f711ae:_bmad/_config/files-manifest.csv:generic-api-key:300 +edf3528742de7c0bd83dc513c159152353f711ae:_bmad/_config/files-manifest.csv:generic-api-key:409 +edf3528742de7c0bd83dc513c159152353f711ae:_bmad/_config/files-manifest.csv:generic-api-key:433 +edf3528742de7c0bd83dc513c159152353f711ae:_bmad/tea/testarch/knowledge/api-testing-patterns.md:generic-api-key:681 + +# Commit 5a40de92 (additional lines): missing suppressions for lines 281, 282, 284, +# 300, 409 in _bmad/_config/files-manifest.csv (SHA256 content checksums of BMAD +# skill files). Same false-positive rationale. Line 433 already suppressed above. +5a40de92116169412709f7be5dec3acba0501953:_bmad/_config/files-manifest.csv:generic-api-key:281 +5a40de92116169412709f7be5dec3acba0501953:_bmad/_config/files-manifest.csv:generic-api-key:282 +5a40de92116169412709f7be5dec3acba0501953:_bmad/_config/files-manifest.csv:generic-api-key:284 +5a40de92116169412709f7be5dec3acba0501953:_bmad/_config/files-manifest.csv:generic-api-key:300 +5a40de92116169412709f7be5dec3acba0501953:_bmad/_config/files-manifest.csv:generic-api-key:409 + +# Commit a7c7e060: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. +a7c7e060359d709d21bc62fe80ba7504cf240c3e:_bmad/_config/files-manifest.csv:generic-api-key:281 +a7c7e060359d709d21bc62fe80ba7504cf240c3e:_bmad/_config/files-manifest.csv:generic-api-key:282 +a7c7e060359d709d21bc62fe80ba7504cf240c3e:_bmad/_config/files-manifest.csv:generic-api-key:284 +a7c7e060359d709d21bc62fe80ba7504cf240c3e:_bmad/_config/files-manifest.csv:generic-api-key:300 +a7c7e060359d709d21bc62fe80ba7504cf240c3e:_bmad/_config/files-manifest.csv:generic-api-key:409 +a7c7e060359d709d21bc62fe80ba7504cf240c3e:_bmad/_config/files-manifest.csv:generic-api-key:433 + +# Commit 00463959: same _bmad/_config/files-manifest.csv CSV rows as above +# (SHA256 content checksums of BMAD skill files). Same false-positive rationale. +00463959f7c39f2c65d7954524ce01e661553511:_bmad/_config/files-manifest.csv:generic-api-key:281 +00463959f7c39f2c65d7954524ce01e661553511:_bmad/_config/files-manifest.csv:generic-api-key:282 +00463959f7c39f2c65d7954524ce01e661553511:_bmad/_config/files-manifest.csv:generic-api-key:284 +00463959f7c39f2c65d7954524ce01e661553511:_bmad/_config/files-manifest.csv:generic-api-key:300 +00463959f7c39f2c65d7954524ce01e661553511:_bmad/_config/files-manifest.csv:generic-api-key:409 +00463959f7c39f2c65d7954524ce01e661553511:_bmad/_config/files-manifest.csv:generic-api-key:433 diff --git a/_bmad/_config/bmad-help.csv b/_bmad/_config/bmad-help.csv index 3e096cbf..d8cf3fa1 100644 --- a/_bmad/_config/bmad-help.csv +++ b/_bmad/_config/bmad-help.csv @@ -46,4 +46,4 @@ Test Architecture Enterprise,bmad-testarch-framework,Test Framework,TF,Initializ Test Architecture Enterprise,bmad-testarch-nfr,NFR Assessment,NR,Non-functional requirements assessment.,,4-implementation,bmad-testarch-automate,,,,,false,test_artifacts,nfr report, Test Architecture Enterprise,bmad-testarch-test-design,Test Design,TD,Risk-based test planning.,,3-solutioning,false,bmad-testarch-framework,,,,false,test_artifacts,test design document, Test Architecture Enterprise,bmad-testarch-test-review,Test Review,RV,Quality audit (0-100 scoring).,,4-implementation,bmad-testarch-automate,,,,,false,test_artifacts,review report, -Test Architecture Enterprise,bmad-testarch-trace,Traceability,TR,Coverage traceability and gate.,,4-implementation,bmad-testarch-test-review,,,,,false,test_artifacts,traceability matrix|gate decision, \ No newline at end of file +Test Architecture Enterprise,bmad-testarch-trace,Traceability,TR,Coverage traceability and gate.,,4-implementation,bmad-testarch-test-review,,,,,false,test_artifacts,traceability matrix|gate decision, diff --git a/scripts/apply-repo-settings.sh b/scripts/apply-repo-settings.sh index 34365411..d145c901 100755 --- a/scripts/apply-repo-settings.sh +++ b/scripts/apply-repo-settings.sh @@ -1,69 +1,31 @@ #!/usr/bin/env bash -# Apply repository-level standard settings via the GitHub API. +# Apply repository-level security settings via the GitHub API. # -# Applies security_and_analysis settings and disables check-suite auto-trigger -# for apps that queue suites on every push without completing them (Claude, -# CodeRabbit), which permanently blocks GitHub auto-merge. +# Called by the apply-repo-settings workflow on path-filtered pushes to main, +# on a weekly schedule (Mondays 06:00 UTC), and via manual dispatch. +# This ensures settings documented in .github/settings.yml stay in effect +# even if they are reset manually or drift over time. # -# Standard: petry-projects/.github/standards/github-settings.md -# #check-suite-auto-trigger-preferences -# -# Usage: -# bash scripts/apply-repo-settings.sh # e.g. TalkTerm -# bash scripts/apply-repo-settings.sh -# GITHUB_REPOSITORY=owner/repo bash scripts/apply-repo-settings.sh # CI form -# -# Environment: -# GH_TOKEN GitHub token. The check-suites API rejects OAuth app -# tokens — use a classic PAT with `repo` scope (or admin). -# ORG GitHub org used to expand a bare repo name (default: -# petry-projects). -# GITHUB_REPOSITORY owner/repo, used when no positional argument is given -# (set automatically by GitHub Actions). -# -# The helpers below are pure and side-effect-free so they can be sourced and -# unit-tested; main only runs when the script is executed directly. +# Required token scope: administration:write +# Usage (local): GH_TOKEN= GITHUB_REPOSITORY=petry-projects/TalkTerm \ +# ./scripts/apply-repo-settings.sh +set -euo pipefail -# App IDs whose check-suite auto-trigger must be disabled. GitHub creates a -# queued suite on every push when auto-trigger is on; these apps never complete -# those suites, permanently blocking auto-merge. -readonly -a CHECK_SUITE_APP_IDS=(1236702 347564) # Claude, CodeRabbit +REPO="${GITHUB_REPOSITORY:?GITHUB_REPOSITORY must be set (e.g. petry-projects/TalkTerm)}" -# resolve_repo -# Resolves the target "owner/repo". Precedence: positional arg, then -# GITHUB_REPOSITORY, then REPO. A bare name is expanded to "/". -# Returns non-zero if no repo can be determined. -resolve_repo() { - local repo="${1:-}" - [ -z "$repo" ] && repo="${GITHUB_REPOSITORY:-}" - [ -z "$repo" ] && repo="${REPO:-}" - [ -z "$repo" ] && return 1 - case "$repo" in - */*) printf '%s' "$repo" ;; - *) printf '%s/%s' "${ORG:-petry-projects}" "$repo" ;; - esac -} +# Validate REPO format (owner/repo) to prevent injection attacks +if ! [[ "${REPO}" =~ ^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$ ]]; then + echo "Error: GITHUB_REPOSITORY must be in format 'owner/repo', got: ${REPO}" >&2 + exit 1 +fi -# auto_trigger_status -# Echoes the current auto_trigger setting for app_id: "true", "false", or -# "missing" (app absent from preferences — never run in repo, so compliant). -auto_trigger_status() { - local json="${1:-}" app_id="$2" - if [ -z "$json" ]; then - printf 'missing' - return 0 - fi - printf '%s' "$json" | jq -r --argjson id "$app_id" \ - '.preferences.auto_trigger_checks // [] - | map(select(.app_id == $id)) - | if length == 0 then "missing" else (.[0].setting | tostring) end' -} +# Settings: secret_scanning, secret_scanning_push_protection, secret_scanning_ai_detection, +# secret_scanning_non_provider_patterns, dependabot_security_updates +# Standard: https://github.com/petry-projects/.github/blob/main/standards/push-protection.md +echo "Applying security_and_analysis settings to ${REPO} ..." -# apply_security_and_analysis -apply_security_and_analysis() { - local repo="$1" - echo "Applying security_and_analysis settings to ${repo} ..." - gh api -X PATCH "repos/${repo}" --input - <<'JSON' +gh api -X PATCH "repos/${REPO}" \ + --input - <<'JSON' { "security_and_analysis": { "secret_scanning": { "status": "enabled" }, @@ -74,53 +36,20 @@ apply_security_and_analysis() { } } JSON -} -# apply_check_suite_prefs -# Disables auto-trigger for any configured app that currently has it enabled. -# Apps that are "missing" (never run) or already "false" are compliant and left -# untouched. The check-suites/preferences GET endpoint is PATCH-only on GitHub -# and returns 404, so when preferences cannot be read we conservatively apply -# the disabling PATCH for every configured app. -apply_check_suite_prefs() { - local repo="$1" - echo "Configuring check-suite auto-trigger preferences for ${repo} ..." +echo "Disabling CodeRabbit (app 347564) and Claude (app 1236702) check-suite auto-trigger ..." - local prefs status app_id - local -a to_disable=() - if prefs=$(gh api "repos/${repo}/check-suites/preferences" 2>/dev/null) && [ -n "$prefs" ]; then - for app_id in "${CHECK_SUITE_APP_IDS[@]}"; do - status=$(auto_trigger_status "$prefs" "$app_id") - case "$status" in - missing) echo " app ${app_id}: never run in repo — compliant, skipping" ;; - false) echo " app ${app_id}: already disabled — skipping" ;; - *) echo " app ${app_id}: auto-trigger enabled — disabling"; to_disable+=("$app_id") ;; - esac - done - else - echo " could not read current preferences — applying disable for all configured apps" - to_disable=("${CHECK_SUITE_APP_IDS[@]}") - fi - - if [ "${#to_disable[@]}" -eq 0 ]; then - echo " already compliant — nothing to do" - return 0 - fi - - local payload - payload=$(printf '%s\n' "${to_disable[@]}" | - jq -Rcn '[inputs | tonumber] | map({app_id: ., setting: false}) | {auto_trigger_checks: .}') - gh api -X PATCH "repos/${repo}/check-suites/preferences" --input - <<<"$payload" +# These apps create queued check suites on every push that are never completed, +# which permanently blocks auto-merge. Disabling auto-trigger prevents GitHub +# from creating those ghost check suites. +gh api -X PATCH "repos/${REPO}/check-suites/preferences" \ + --input - <<'JSON' +{ + "auto_trigger_checks": [ + { "app_id": 347564, "setting": false }, + { "app_id": 1236702, "setting": false } + ] } +JSON -# Run main only when executed directly, so tests can source the helpers. -if [ "${BASH_SOURCE[0]:-$0}" = "$0" ]; then - set -euo pipefail - repo="$(resolve_repo "${1:-}")" || { - echo "Usage: $0 (or set GITHUB_REPOSITORY)" >&2 - exit 1 - } - apply_security_and_analysis "$repo" - apply_check_suite_prefs "$repo" - echo "Done." -fi +echo "Done."