Repository navigation
fix: encode compliance-fix learnings into standards and Claude prompt #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
16b0f25
11c1450
80e54a5
714a589
57dae28
65d0f17
e94809e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -66,6 +66,10 @@ jobs: | |||||||||||||||||||||||||||||||
| issues: write | ||||||||||||||||||||||||||||||||
| actions: read | ||||||||||||||||||||||||||||||||
| checks: read | ||||||||||||||||||||||||||||||||
| # Note: GitHub Actions does NOT expose an "administration" permission scope. | ||||||||||||||||||||||||||||||||
| # Admin operations (create rulesets, enable Discussions, etc.) work via the | ||||||||||||||||||||||||||||||||
| # GH_PAT_WORKFLOWS token below, which must be a classic PAT with `repo` scope | ||||||||||||||||||||||||||||||||
| # (or fine-grained with Administration:write) for those calls to succeed. | ||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||
| - name: Checkout repository | ||||||||||||||||||||||||||||||||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||||||||||||||||||||||||||||||||
|
|
@@ -82,11 +86,48 @@ jobs: | |||||||||||||||||||||||||||||||
| additional_permissions: | | ||||||||||||||||||||||||||||||||
| actions: read | ||||||||||||||||||||||||||||||||
| checks: read | ||||||||||||||||||||||||||||||||
| # yamllint disable rule:line-length | ||||||||||||||||||||||||||||||||
| claude_args: | | ||||||||||||||||||||||||||||||||
| --allowedTools "Bash(gh pr create:*),Bash(gh pr view:*),Bash(gh pr comment:*),Bash(gh issue comment:*),Bash(gh run view:*),Bash(gh run watch:*),Edit,Write" | ||||||||||||||||||||||||||||||||
| --allowedTools "Bash(gh pr create:*),Bash(gh pr view:*),Bash(gh pr comment:*),Bash(gh issue comment:*),Bash(gh run view:*),Bash(gh run watch:*),Bash(gh api:*),Bash(gh label create:*),Edit,Write" | ||||||||||||||||||||||||||||||||
| # yamllint enable rule:line-length | ||||||||||||||||||||||||||||||||
| prompt: | | ||||||||||||||||||||||||||||||||
| Implement a fix for issue #${{ github.event.issue.number }}. | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| **Standards-conformance rules — read these before writing any code:** | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| - **For workflow files** (`.github/workflows/*.yml`): if a template | ||||||||||||||||||||||||||||||||
| exists in `petry-projects/.github/standards/workflows/` for what | ||||||||||||||||||||||||||||||||
| you're adding, **copy it verbatim** rather than writing from | ||||||||||||||||||||||||||||||||
| scratch. Available templates: `agent-shield.yml`, `claude.yml`, | ||||||||||||||||||||||||||||||||
| `dependabot-automerge.yml`, `dependabot-rebase.yml`, | ||||||||||||||||||||||||||||||||
| `dependency-audit.yml`, `feature-ideation.yml`. Fetch via: | ||||||||||||||||||||||||||||||||
| `gh api repos/petry-projects/.github/contents/standards/workflows/<file>.yml --jq '.content' | base64 -d` | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
| `gh api repos/petry-projects/.github/contents/standards/workflows/<file>.yml --jq '.content' | base64 -d` | |
| `gh api -H "Accept: application/vnd.github.raw" repos/petry-projects/.github/contents/standards/workflows/<file>.yml > .github/workflows/<file>.yml` |
Copilot
AI
Apr 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, this prompt lists claude.yml as one of the standards/workflows/ templates to copy verbatim, but standards/workflows/claude.yml is not currently a thin caller (it runs the Claude action directly). That makes the instruction ambiguous for repos trying to follow the new “template-first” rule; align the prompt with the actual template, or update the template to match the reusable-workflow delegation model.
| you're adding, **copy it verbatim** rather than writing from | |
| scratch. Available templates: `agent-shield.yml`, `claude.yml`, | |
| `dependabot-automerge.yml`, `dependabot-rebase.yml`, | |
| `dependency-audit.yml`, `feature-ideation.yml`. Fetch via: | |
| `gh api repos/petry-projects/.github/contents/standards/workflows/<file>.yml --jq '.content' | base64 -d` | |
| Adapt only when the file genuinely needs repo-specific content. | |
| you're adding, use that template instead of writing from scratch. | |
| Available templates: `agent-shield.yml`, `claude.yml`, | |
| `dependabot-automerge.yml`, `dependabot-rebase.yml`, | |
| `dependency-audit.yml`, `feature-ideation.yml`. Fetch via: | |
| `gh api repos/petry-projects/.github/contents/standards/workflows/<file>.yml --jq '.content' | base64 -d` | |
| For `claude.yml`, copy the standard thin caller template and keep | |
| it delegating to the reusable Claude workflow rather than running | |
| the Claude action inline. Adapt templates only when the file | |
| genuinely needs repo-specific content. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,39 @@ repository must implement. | |
|
|
||
| --- | ||
|
|
||
| ## Using Templates from `standards/workflows/` | ||
|
|
||
| > **Rule:** When fixing a compliance finding by adding a workflow file, **copy | ||
| > the template from [`standards/workflows/`](workflows/) verbatim.** Do not | ||
| > generate the file from scratch, even if the change seems trivial. The | ||
| > templates are the source of truth — anything generated from scratch is, by | ||
| > definition, drift. | ||
|
|
||
| Available templates: | ||
|
|
||
| | Template | Purpose | | ||
| |----------|---------| | ||
| | [`agent-shield.yml`](workflows/agent-shield.yml) | Deep agent-config security scan via `ecc-agentshield` | | ||
| | [`claude.yml`](workflows/claude.yml) | Thin caller delegating to the org-level reusable Claude Code workflow | | ||
| | [`dependabot-automerge.yml`](workflows/dependabot-automerge.yml) | Auto-approve and squash-merge eligible Dependabot PRs | | ||
| | [`dependabot-rebase.yml`](workflows/dependabot-rebase.yml) | Rebase Dependabot PRs on demand | | ||
| | [`dependency-audit.yml`](workflows/dependency-audit.yml) | Multi-ecosystem audit (npm, pnpm, gomod, cargo, pip) | | ||
| | [`feature-ideation.yml`](workflows/feature-ideation.yml) | BMAD Method ideation pipeline (BMAD-enabled repos only) | | ||
|
Comment on lines
+19
to
+26
|
||
|
|
||
| **Adapt only when the template genuinely requires repo-specific content** (e.g., a | ||
| project name in a comment, a different cron schedule for a known reason). Anything | ||
| beyond surface adaptation indicates either a missing template or a missing standard | ||
| — file an issue against `petry-projects/.github` rather than diverging silently. | ||
|
|
||
| **Fetching a template programmatically** (e.g., from a Claude Code automation run): | ||
|
|
||
| ```bash | ||
| gh api repos/petry-projects/.github/contents/standards/workflows/<file>.yml \ | ||
| --jq '.content' | base64 -d > .github/workflows/<file>.yml | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Required Workflows | ||
|
|
||
| Every repository MUST have these 7 workflows. Reusable templates for Dependabot | ||
|
|
@@ -544,6 +577,31 @@ version for human readability. | |
| Dependabot keeps pinned SHAs up to date via the `github-actions` ecosystem | ||
| entry in `dependabot.yml`. | ||
|
|
||
| ### Looking Up the Correct SHA | ||
|
|
||
| > **Never guess or fabricate a SHA.** A SHA that doesn't exist in the upstream | ||
| > repo will fail at runtime — and worse, may "pass CI" if the job that uses it | ||
| > is conditionally skipped, leaving a latent failure waiting to bite the next | ||
| > developer. | ||
|
|
||
| Use the GitHub API to resolve a tag or branch to its current commit SHA: | ||
|
|
||
| ```bash | ||
| # For a tag (e.g., v6.0.2) | ||
| gh api repos/actions/checkout/git/refs/tags/v6.0.2 --jq '.object.sha' | ||
|
|
||
| # For a branch (e.g., stable) | ||
| gh api repos/dtolnay/rust-toolchain/branches/stable --jq '.commit.sha' | ||
|
|
||
| # Verify a SHA exists in the upstream repo before pinning | ||
| gh api repos/actions/checkout/commits/de0fac2e4500dabe0009e67214ff5f5447ce83dd --jq '.sha' | ||
| ``` | ||
|
|
||
| **If the lookup fails or the network is unavailable, do not pin.** Leave the | ||
| action with its tag reference and document the blocker in the PR body so a | ||
| human can complete the fix. A correct unpinned reference is better than an | ||
| incorrect pinned one. | ||
|
|
||
| > **Note on examples in this document:** The "Workflow Patterns by Tech Stack" | ||
| > section uses tag references (e.g., `@v4`) for readability since those are | ||
| > illustrative patterns, not copy-paste templates. The "Required Workflows" | ||
|
|
@@ -580,6 +638,19 @@ For single-job workflows, top-level least-privilege permissions are acceptable | |
| | CodeQL | `actions: read`, `security-events: write`, `contents: read` | | ||
| | Dependabot auto-merge | `contents: read`, `pull-requests: read` (+ app token for merge) | | ||
|
|
||
| > **Note on admin operations from Claude Code:** GitHub Actions does **not** | ||
| > expose an `administration` permission scope. The valid set is documented at | ||
| > [docs.github.com](https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs). | ||
| > Admin-level operations the `claude-issue` job needs — creating repository | ||
| > rulesets, enabling Discussions, modifying repo settings — must be performed | ||
| > with a token that already carries the right scope. The reusable workflow | ||
| > passes `GH_PAT_WORKFLOWS` to `claude-code-action` for exactly this reason: | ||
| > as long as that org-level secret is a classic PAT with `repo` scope (which | ||
| > includes admin capability for the authenticated user's repos) or a | ||
| > fine-grained PAT with `Administration: Read and write`, admin calls | ||
| > succeed. Granting a non-existent workflow permission has no effect and | ||
| > will fail `actionlint`. | ||
|
|
||
| --- | ||
|
|
||
| ## Organization-Level Secrets for Standard CI | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding
administration: writehere will only affect the job-scopedGITHUB_TOKEN. In this job the action later receivesgithub_token: ${{ secrets.GH_PAT_WORKFLOWS }}(a separate PAT), so unless that PAT is guaranteed to be present and to have equivalent admin capabilities, the new permission may not actually enable label/ruleset/discussions changes. Consider having the action default to${{ secrets.GH_PAT_WORKFLOWS || github.token }}(or documenting that the PAT must include admin-level scopes) so the permission grant is effective.