Skip to content

Monthly Workflow Audit - July 2026 #17

Description

@github-actions

Monthly Workflow Audit - July 2026

Review Period: 2026-07-01 to 2026-07-31

Repository Activity Summary

  • PRs merged: 3
  • Issues closed: 1
  • Claude-labeled PRs: 3
  • Claude-labeled issues: 3
  • Failed PR attempts: 0

Verified against the API on 2026-08-01 and all five counts are correct: PRs #9, #11, #13 merged; issue #12 closed; claude-labelled issues #10, #12, #14 created or active in the period. This is the first audit here whose numbers did not need hand-correction — the pull-requests: read scope added by the shared-workflow migration (7187af2) fixed the silent-zero bug diagnosed in #10.

Audit Tasks

Please analyze the repository activity from the review period and provide:

  1. Pattern Analysis: Identify common failure patterns or workflow bottlenecks
  2. Feature Discovery: Search for new GitHub/Claude Code features that could improve our workflow
  3. Workflow Improvement Suggestions: Recommend specific changes to instructions, scripts, workflows, labels
  4. Evidence: Anchor every finding to a specific issue, pull request, file or line

Deliverables

  • Post analysis as comment on this issue
  • If no improvements needed, close this issue
  • If improvements suggested, keep issue open for human review
  • Once human approves suggestions, human will remove discuss label → Claude can implement changes

Audit Findings (July 2026)

1. Pattern Analysis

Execution was flawless; configuration was not. Zero failed, cancelled or timed-out workflow runs across the last 200 runs since 2026-07-01. Zero rework cycles — PRs #9, #11 and #13 each landed in a single commit. Every problem below is a configuration regression introduced on 2026-07-31/08-01 by the shared-workflow migration, not an execution failure.

The July theme is that CI job renames silently break branch protection, and it happened twice in two days.

P1 — 🔴 The required check check can never report again; every PR to main is permanently blocked

Branch protection on main requires two contexts:

$ gh api repos/trancecode/ecs/branches/main/protection
"contexts": ["check", "analysis / analysis"]

Commit 486394d (2026-08-01) turned go.yml's check job into a reusable-workflow call:

jobs:
  check:
    uses: trancecode/github-workflows/.github/workflows/go-build-test.yml@main

The shared workflow's job id is build (go-build-test.yml:58). A reusable call reports as <caller-job> / <called-job>, so the run on main reports check / build:

$ gh run view 30675316996 --json jobs --jq '.jobs[].name'
check / build          # 486394d
$ gh run view 30675023376 --json jobs --jq '.jobs[].name'
check                  # 9a93ba8, the commit before

The literal context check will never be produced again, so it can never turn green. PR #15 is already mergeStateStatus: BLOCKED and rebasing it will not help.

The same rename happened to analysis in 9cb1acb, and there branch protection was updated to analysis / analysis. 486394d made the identical change to go.yml without the matching protection update.

Fix: update the required context from check to check / build. Requires admin rights on branch protection — Claude's token cannot change it.

P2 — 🟠 paths-ignore restored on a required check, re-creating the PR #8 deadlock

386f1d6 (2026-07-31) re-added path filters to analysis.yml:

  pull_request:
    branches: [main]
    paths-ignore: ['**.md', 'LICENSE', 'doc/**']

analysis / analysis is a required context. A doc-only PR skips the workflow, the required context never reports, and the PR is permanently BLOCKED. This is exactly the incident from PR #8, fixed in 5ddfa1e on 2026-06-30 with the commit message "Run Code Analysis on all PRs to unblock doc-only changes".

The June audit (#10) called this out as a standing convention — "required status checks must never carry paths-ignore/paths filters" — and left one open question: where should that convention be written down? That question was still unanswered on 2026-07-31, and the regression landed the same day, from a cross-repo migration that copied the filter back in from webmirror. An unwritten convention did not survive its first month.

Secondary: doc/** does not match anything here — this repo's docs live in docs/. It is dead config copied from another repository; **.md happens to cover docs/**/*.md anyway.

P1 and P2 compound: a doc-only PR skips analysis, and no PR can satisfy check.

P3 — 🟡 Issue #16 is invisible to the autonomous agent, and is now obsolete anyway

#16 ("Pin staticcheck and deduplicate static analysis in analysis.yml") carries only the ready label. Work detection only selects issues labelled claude, so #16 will never be picked up — it has sat since 2026-07-31 with no path to being worked.

It is also stale. Both of its items were resolved by the migration:

  • Pin staticcheckanalysis.yml no longer installs anything. The shared go-analysis.yml pins staticcheck-version: '2026.1', with the input documented "Never use @latest: a toolchain that moves underneath CI fails builds on commits that changed nothing" — the same argument Pin staticcheck and deduplicate static analysis in analysis.yml #16 makes.
  • Deduplicate static analysis — the shared workflow passes --disable=staticcheck to golangci-lint ("one owner per tool"), and 9a93ba8 removed the duplicated gofmt and go vet steps from go.yml.

Note this resolution is Option B (pin standalone), not the Option A (fold into golangci-lint) that #10 recommended and verified against golangci-lint v2.9.0 sources. The shared workflow made that call centrally, with a stated rationale — golangci-lint's bundled staticcheck also enables the QF family, so running both reports one tool twice with different opinions. #10's Option A question is therefore answered by fact rather than by decision, and #10's "Next Steps" no longer describes work that exists.

P4 — 🟡 The activity metric is blind to most of this repo's July change

The counts are right, but they measure the wrong thing. Five commits landed directly on main in July with no PR and no issue:

Commit Change
b7464f5 EntityId.Compare — total order consistent with allocation order
8c55772 EntityId binary marshaling
90aeb4e World restore API: EntityCounter, RestoreEntityCounter, RestoreEntity
8a5901b World.String()
0fa6ecc Pages deploy retry

Four of the five add exported API. CLAUDE.md's "Interactive Mode Git Workflow" explicitly permits direct commits to main, so no rule was broken. But CLAUDE.md also states "API stability is the primary design driver, because multiple repositories depend on this module", and a PR-shaped activity metric reports "3 PRs merged" for a month whose actual public API growth happened entirely outside PRs. The audit cannot see the changes that matter most to this repo.

2. Feature Discovery

July 2026 releases, checked for relevance here:

  • Self-repository syntax $/ (2026-07-30) — resolves an action or reusable workflow to the workflow's own repository at the running commit. Not applicable: every reusable workflow this repo calls is cross-repo (trancecode/github-workflows@main), which is precisely what $/ does not cover.
  • Copilot CLI in Actions with built-in GITHUB_TOKEN — no PAT needed. Not relevant; this repo's agent is Claude Code, driven externally.
  • Immutable OIDC subject claims (repos created/renamed after 2026-07-15) — this repo uses no OIDC.
  • Dependabot 3-day release cooldown, now on by default — no effect: zero third-party dependencies, deliberately.
  • Claude Code July — Opus 5 as default, and --forward-subagent-text / CLAUDE_CODE_FORWARD_SUBAGENT_TEXT to include subagent text in stream-json output. That flag would improve autonomous-session log capture, but it belongs to the scheduler infra, not this repo. Routed centrally per Monthly Workflow Audit - June 2026 #10's resolved scoping rule.

Previously suggested, still unimplemented, circumstances unchanged: GitHub Agentic Workflows (public preview, 2026-06-11) and Claude Code fallbackModel, both flagged in #10 as centralized-infra concerns. Nothing changed in July to revisit either. GitHub Actions parallel steps remain not worth the complexity for a single tiny package.

Nothing released in July 2026 requires a change to this repository's files. All four action items above come from repository activity, not from new platform capability.

3. Workflow Improvement Suggestions

Prioritized, all evidence-anchored above:

  1. Update branch protection: checkcheck / build (P1). Unblocks PR Design: concurrent mutation of disjoint entity sets #15 and every future PR. Human action — Claude cannot modify branch protection.
  2. Remove paths-ignore from analysis.yml (P2), restoring 5ddfa1e. One-line-class change Claude can make.
  3. Write the convention down (P2). Both P1 and P2 are the same failure — a required status check whose context name or trigger can change without branch protection changing with it. Monthly Workflow Audit - June 2026 #10 asked where this belongs and recommended trancecode/github-workflows with no repo-local duplication; the July regression is the evidence for deciding it now rather than deferring again. The convention has two clauses: required checks carry no path filters, and renaming a required job — including wrapping it in a reusable-workflow call — must update branch protection in the same change.
  4. Close Pin staticcheck and deduplicate static analysis in analysis.yml #16 as resolved by 7187af2 / 9cb1acb / 9a93ba8, noting it was settled as Option B rather than Monthly Workflow Audit - June 2026 #10's Option A. Alternatively add the claude label if any residue is wanted — but as written, there is nothing left to do.
  5. Count commits on main, not just merged PRs, in the shared monthly-audit.yml (P4). git log --first-parent, split into PR merges vs direct commits. Central change in trancecode/github-workflows, benefits every repo; out of scope for this repo's files.

Next Steps

When the discuss label is removed, Claude will:

  • Edit .github/workflows/analysis.yml to remove the paths-ignore blocks from both the push and pull_request triggers (P2), restoring the state 5ddfa1e established.
  • Not touch branch protection (P1) — no token permission; this stays a human action.
  • Not open a PR against trancecode/github-workflows for items 3 and 5 unless the answers below direct it here.

Open questions:

  • P1: confirm branch protection will be updated to check / build, or say instead that 486394d should be reverted so the bare check context returns. Until one of these happens, no PR — including the one this issue would produce — can merge.
  • P2: should Claude drop paths-ignore from this repo's analysis.yml directly, or should the fix be a paths-ignore-free default enforced centrally in trancecode/github-workflows?
  • P2/Monthly Workflow Audit - June 2026 #10 carry-over: where does the required-check convention live? Monthly Workflow Audit - June 2026 #10's recommendation was central-only. Confirm, or name a repo-local home.
  • P3: close Pin staticcheck and deduplicate static analysis in analysis.yml #16 as resolved by the migration, or keep it open with the claude label added?
  • P4: should the "commits on main" metric be raised as an issue against trancecode/github-workflows, and by whom?

✨ Content generated by Claude AI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claudeTicket that should be handled by ClaudediscussIssues that need discussion before implementationinput requiredDerived from whether the last interaction was Claude-authored. Do not set by handreadyDerived: no open blocked-by dependencies. Do not set by hand

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions