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
14 changes: 10 additions & 4 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Keeps the SHA-pinned actions inside these reusable workflows current.
# Dependabot reads the `# vX` comment on each `uses:` pin, watches for new
# releases, and opens grouped PRs that bump the SHA (and the comment).
# The actions inside these reusable workflows float on their major tag (@v7, @v1), so every run
# picks up minor and patch releases on its own and Dependabot has nothing to propose below a
# major. Policy (Maria, 2026-09-10): majors are the only action bumps that get a PR anywhere —
# a breaking change is fixed after the fact rather than every patch being shepherded fleet-wide.
#
# Two groups, by risk:
# Two groups, by risk, for those major bumps:
# • github-owned (actions/*) — GitHub-maintained, low-risk →
# AUTO-MERGED by dependabot-auto-merge.yml
# • claude-code-action (anthropics/*) — holds AGENTS_GH_PAT → a human reviews
Expand All @@ -16,6 +17,11 @@ updates:
directory: "/" # scans .github/workflows/
schedule:
interval: "weekly"
# Minor and patch bumps never get a PR: a floating ref already has them, and this closes the
# reported Dependabot edge that rewrites a major-tag ref into a pinned patch.
ignore:
- dependency-name: "*"
update-types: ["version-update:semver-minor", "version-update:semver-patch"]
groups:
github-owned:
patterns:
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ name: Dependabot auto-merge (GitHub-owned actions)
# (actions/checkout, actions/upload-artifact, actions/download-artifact — all
# GitHub-maintained, low-risk). The `claude-code-action` group is a SEPARATE
# Dependabot group and is deliberately NOT auto-merged: it holds AGENTS_GH_PAT,
# so a human reviews those bumps.
# so a human reviews those bumps. Since the actions float on their major tag,
# the only PRs either group produces are major bumps.
#
# Uses only the built-in `gh` CLI (no external action) so it is not subject to
# the allowed-actions allowlist. The approval counts because the repo has
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dependabot-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
id: download
if: steps.provenance.outputs.report == 'true'
continue-on-error: true # a real-outcome run with no artifact must still ping a human, not error the job
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
uses: actions/download-artifact@v8
with:
name: dependabot-validation
path: _artifacts
Expand Down Expand Up @@ -115,7 +115,7 @@ jobs:
# to initiate it does not widen the trust surface. continue-on-error: a verdict-generation hiccup
# must never drop the human-ping in the steps below.
continue-on-error: true
uses: anthropics/claude-code-action@c81e3bc69d1b18badbb63ba39581218f02421678 # v1.0.201
uses: anthropics/claude-code-action@v1
env:
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: "1" # anthropics/claude-code-action#1499; see templates/github/claude.yml
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dependabot-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:

- name: Checkout PR head (UNTRUSTED — no credentials persisted)
if: steps.gate.outputs.run == 'true'
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false
Expand Down Expand Up @@ -189,7 +189,7 @@ jobs:

- name: Upload validation artifact
if: ${{ always() && steps.gate.outputs.run == 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@v7
with:
name: dependabot-validation
path: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@v7

# Pinned release + checksum instead of the upstream `rhysd/actionlint` action: the org
# enforces a selected-actions allowlist, so a dependency-free download is one less thing to
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pr-first-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:

- name: Checkout PR head (same-repo / trusted)
if: ${{ steps.guard.outputs.same_repo == 'true' && steps.ticket.outputs.has_ticket == 'false' }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
Expand Down Expand Up @@ -148,7 +148,7 @@ jobs:
- name: Run /code-review (comments only — execution-free, read-only tools)
id: review
if: ${{ steps.guard.outputs.same_repo == 'true' && steps.ticket.outputs.has_ticket == 'false' }}
uses: anthropics/claude-code-action@c81e3bc69d1b18badbb63ba39581218f02421678 # v1.0.201
uses: anthropics/claude-code-action@v1
env:
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: "1" # anthropics/claude-code-action#1499; see templates/github/claude.yml
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ticketed-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ jobs:

- name: Checkout the PR head (read-only review)
if: steps.resolve.outputs.skip == 'false' && steps.round.outputs.over == 'false'
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@v7
with:
ref: ${{ steps.resolve.outputs.head_sha }}
fetch-depth: 0
Expand Down Expand Up @@ -200,7 +200,7 @@ jobs:
# Don't abort the job on a review error — the decide step turns an errored review into an
# honest handoff (never a false "clean"). The review-step OUTCOME is what it reads.
continue-on-error: true
uses: anthropics/claude-code-action@c81e3bc69d1b18badbb63ba39581218f02421678 # v1.0.201
uses: anthropics/claude-code-action@v1
env:
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: "1" # anthropics/claude-code-action#1499; see templates/github/claude.yml
with:
Expand Down
8 changes: 5 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ caveats: README "Release + repin order"; wave mechanics and fleet counts: `docs/
the lead-in that un-scopes the tripwire from them) is kit-side and must survive the re-copy. Parity
is checked with whitespace collapsed (the kit flattens one paragraph break).
- `DRIVER_AGENTS_REF` lives in `claude.yml` **and** `shopify-tool-smoke.yml`; same SHA in both, or the
smoke test verifies a revision the implementer never runs. Dependabot cannot bump it (raw SHA in
`env:`), nor any action pin inside `templates/` (it scans only `.github/workflows/`) — check
`actions/checkout` and `claude-code-action` against the reusables' pins at every tag.
smoke test verifies a revision the implementer never runs. Dependabot cannot bump it: a raw SHA in
`env:`, and it scans only `.github/workflows/`, never `templates/`. That is also why the kit's
whole-file workflows reference third-party actions by major tag (`@v1`, `@v7`) — a SHA there is a
pin nothing bumps while a fleet repo's Dependabot bumps its copy when the action releases. The
reusables float the same way; majors are the only action bumps that get a PR anywhere.
- `dependabot-validate` stub `name:` stays byte-identical (`Dependabot validate`) — `-report`'s
`workflow_run` name-matches it. The job always runs and branches internally; never `if:`-skip it.
- Never `pull_request_target`. Never set `anthropic_api_key` (overrides OAuth, bills at API rates).
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,14 @@ Waved to all 21 pairs on 2026-08-02; fleet uniform, 108 pins, zero stale.
- Wave mechanics, the guards worth keeping, and what the pin audit cannot see:
[`docs/fleet-operations.md`](docs/fleet-operations.md).

**Template pins are manual.** `.github/dependabot.yml` uses `directory: "/"`, which only scans
`.github/workflows/` — nothing will ever bump an action pin inside `templates/`. Check
`templates/github/claude.yml`'s `actions/checkout` + `claude-code-action` pins against the
reusables' whenever you cut a tag. The same applies to `DRIVER_AGENTS_REF` — which appears in **two**
**Template pins are manual — so the kit's third-party actions float.** `.github/dependabot.yml` uses
`directory: "/"`, which only scans `.github/workflows/` — nothing will ever bump a pin inside
`templates/`, while a fleet repo running the `github-actions` updater bumps its deployed copy when the
action itself releases, so a SHA there guaranteed the fleet ran ahead of the kit and each wave rolled
it back (foundrae-blackridge #174). The three whole-file kit workflows therefore reference
`actions/checkout@v7`, `actions/upload-artifact@v7` and `anthropics/claude-code-action@v1`, which
Dependabot leaves alone until a new major exists. The reusables float the same way, so the only action
bump that ever gets a PR — here or in a fleet repo — is a major. `DRIVER_AGENTS_REF` stays manual — it appears in **two**
kit files, `claude.yml` and `shopify-tool-smoke.yml`, and must carry the same pin in both or the
smoke test verifies a revision the implementer never runs — and to the `VERSION` + `SHA256` pair in
`lint.yml`, which must be bumped together or the checksum check fails the job.
Expand Down Expand Up @@ -404,7 +408,8 @@ Two files in `.github/workflows/` are **this repo's own CI**, not products — t
and never ship to the fleet: `lint.yml` (actionlint + shellcheck over the reusables *and* the kit, so a
broken workflow can't reach consumer repos) and `dependabot-auto-merge.yml` (auto-merges this repo's own
`github-owned` Dependabot bumps; the `claude-code-action` group is deliberately excluded, so those land by
hand).
hand). Both are quiet below a major: every third-party action here and in the kit floats on its major
tag, so a run already has each minor and patch, and `.github/dependabot.yml` ignores everything but majors.

**`actionlint` is a required status check on `main`** (set 2026-08-02) — before that, `lint.yml` could
report red without being able to block. Note the name collision: this repo's own `lint.yml` and the kit's
Expand Down Expand Up @@ -444,7 +449,7 @@ number, same-repo head). **Never use `pull_request_target`.**
## Consuming it (caller stubs)

Install the matching stubs from **this repo's `templates/github/`** into a repo's `.github/workflows/`.
Pin every `uses:` to an **immutable commit SHA** (decided 2026-06-17); a bot (Renovate/Dependabot) bumps the
Pin every `uses:` of this repo's reusables to an **immutable commit SHA** (decided 2026-06-17); a bot (Renovate/Dependabot) bumps the
SHAs. The `dependabot-validate` stub's `name:` MUST stay byte-identical (`Dependabot validate`) across all
repos — the `dependabot-report` stub's `workflow_run` trigger name-matches it exactly, and a drift silently
disables the human-ping.
Expand Down
12 changes: 7 additions & 5 deletions docs/HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ Avara #195 diagnosis gets confirmed.

- **The first real ticket through v1.15.0.** The guard step should stay quiet; if it fires, the
failure note lands on the issue and the transcript is in the run log (`show_full_output`).
- **foundrae-blackridge@staging** will drift again: its Dependabot bumped `claude-code-action` to
1.0.210 on 2026-09-02 (#174) and the wave brought it back to the kit's 1.0.201. The audit reports
that as the kit being behind, which is the correct reading.
- **Major bumps of the kit's floated actions.** `actions/checkout@v7`, `actions/upload-artifact@v7`
and `anthropics/claude-code-action@v1` float in the kit; when a new major ships, a fleet repo's
Dependabot moves ahead and the audit reads the kit as behind until the kit's major is bumped.
Below a major boundary the foundrae-blackridge #174 drift-and-rollback cannot recur.
- **The cooldown exemption** is unverified live until a tag lands and a repo carrying the kit block
bumps the same day; vite-plugin-shopify-clean is the one to watch at the next tag.
- **WebSearch/WebFetch** stay off: the caveat's condition (#690 fixed **and** the pin bumped) is half
met by this release; #690 was still open at 2026-07-28. Re-check at the next pin bump.
- **WebSearch/WebFetch** stay off until #690 ships a fix (still open at 2026-07-28); the action
floats on `v1`, so the fix arrives on its own and the caveat comment in `claude.yml` is what gets
removed.
- A human `@claude` (tag mode) still gets the action's own co-author text; the nine-item quality
standard is global to `--append-system-prompt` — both unchanged.

Expand Down
2 changes: 1 addition & 1 deletion docs/claude-yml-wave-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ un-started Plan B work; it is the ride-along list for the wave after `v1.15.0`.
| **Figma wrapper wiring** | `claude_args` gains `--mcp-config '{"mcpServers":{"figma":{…}}}'` as inline JSON (never a file path — dropped in tag mode), `--allowedTools` gains the read-only `mcp__figma__*` tools, and `lint.yml`'s quote gate moves **4 → 6** in the same commit. Wiring and tool list: [`figma-mcp-in-ci.md`](figma-mcp-in-ci.md). | The read-only REST-backed wrapper exists in driver-agents and answers one call from a throwaway Actions run. Not `mcp.figma.com`, so that doc's re-open tripwire does not apply. |
| **Figma caveat rewrite** | CAVEAT 2 above `--allowedTools` says no rail can read a design; once the wrapper is wired it says what the implementer can read (node JSON, rendered PNGs) and that writes are never offered. | Same as above. |
| **Macroscope CLI in the run** | A setup step installs the CLI with the Claude Code plugin and the issue prompt runs `/macroscope:autoloop` before the pre-review. | A non-interactive credential. The installer takes `--tools claude --yes`, but auth is a browser wizard under `~/.macroscope` and reviews bill agent credits; nothing in the docs or installer offers a token path. Ask Macroscope; same shape as the Figma blocker until answered. |
| **WebSearch / WebFetch** | Re-add to `--allowedTools`. | anthropics/claude-code-action#690 ships a fix (open as of 2026-07-28). The v1.15.0 pin bump does not change this. |
| **WebSearch / WebFetch** | Re-add to `--allowedTools`. | anthropics/claude-code-action#690 ships a fix (open as of 2026-07-28). The kit floats on `v1`, so the fix arrives on its own; the caveat comment is what gets removed. |
| **Model** | None planned; `--model fable --effort xhigh` stays. | The Fable billing answer above; fallback is `--model opus` (MODEL NOTE in `claude.yml`). |

Anything that only touches the kit and none of these gates can ride the next reusable tag instead —
Expand Down
10 changes: 6 additions & 4 deletions docs/fleet-operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ carried `a54c91e` in a pin line, so no diff base produced a matching `-` line an
have rejected all five files on target #1. **Sed the pin; don't patch it.**

**3. Per-repo state that must survive.** `SHOPIFY_STORE_NAME` in `claude.yml` and
`shopify-tool-smoke.yml`, and any Dependabot-bumped action pins. Surveyed at v1.11.0: the fleet's
`shopify-tool-smoke.yml` — nothing else: the kit's third-party actions float on major tags, and a
repo's Dependabot moving one to a new major is drift for the wave to roll back, not state to keep.
Surveyed at v1.11.0: the fleet's
`claude.yml` copies were byte-identical to the kit except Avara's store handle, and there was no
Dependabot drift — but survey, don't assume.

Expand Down Expand Up @@ -201,9 +203,9 @@ Two things worth knowing about check 3:
correctly-waved repo is *supposed* to have. Second, trailing blank lines and the final newline:
the three pairs waved without a final newline are otherwise identical, and permanently-red rows
for a byte nobody can act on is how a detector stops being read. Internal blank lines *are*
compared. Everything else that differs is reported, third-party action pins
included: a repo whose Dependabot bumped `actions/checkout` past the kit's pin is drift worth
seeing, and it means the kit is behind, not that the repo is wrong.
compared. Everything else that differs is reported, third-party action refs
included: a repo whose Dependabot moved `actions/checkout@v7` to `@v8` ahead of the kit is drift
worth seeing, and it means the kit is behind, not that the repo is wrong.
- **`DriverDigital/workflows` itself is skipped.** Its `.github/workflows/` holds the *reusables*,
which share basenames with the stubs that call them — so comparing it against `templates/` would
report four phantom drifts — the three Dependabot stubs plus `lint.yml`, whose kit copy is a
Expand Down
11 changes: 5 additions & 6 deletions docs/reusable-conversion-scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ Three things moved. None of them flips the status on its own.
- **The business case shrank.** "A wave is re-copying the whole file while hand-preserving per-repo edits"
stopped being true at v1.13.0 — `tools/fleet-wave.sh` does exactly that mechanically and
`fleet-pin-audit.sh` compares whole-file content. What is left of the case: churn (`claude.yml` changed
in 6 of the last 8 releases), moving three action pins somewhere Dependabot can see them, and one
central `DRIVER_AGENTS_REF`. Effort is unchanged at **20–27h**.
in 6 of the last 8 releases) and one central `DRIVER_AGENTS_REF` — the three action refs left the case
when the kit floated them on major tags. Effort is unchanged at **20–27h**.

---

Expand All @@ -65,10 +65,9 @@ and `DRIVER_AGENTS_REF` stays hand-edited fleet-wide for as long as `shopify-too
file (open decision 1). What conversion removes is the *logic* that a wave could hand-carry a subset of —
which is the specific failure that produced the Avara incident.

Secondary win: `actions/checkout` (`templates/github/claude.yml:130`), `claude-code-action` (`:310`) and
`actions/upload-artifact` (`:496`, added by v1.8.0) move out of `templates/` and into `.github/workflows/`,
which `.github/dependabot.yml` (`directory: "/"`) actually scans — converting **three** documented manual pins
into bot-managed ones.
Secondary win, gone: the three third-party action refs in `templates/github/claude.yml` float on major
tags now, so nothing there is a manual pin for the conversion to move; `DRIVER_AGENTS_REF` is the one
central pin left.

---

Expand Down
5 changes: 3 additions & 2 deletions templates/github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ Requested, approved → Ready for QA) were retired with the review leg at v1.12.
entry already → keep it and set its `interval` to `daily`. Dependabot scans the default branch
only, so a repo carrying the kit on other branches (Palmers) needs one entry per branch with
`target-branch:` set.
**Re-copying into a repo that already has the kit?** Preserve that repo's own Dependabot action
pins — re-copy the workflow bodies, but don't clobber pins Dependabot has since bumped there.
**Re-copying into a repo that already has the kit?** Let the wave do it
(`tools/fleet-wave.sh --only <repo>`): whole-file, with `SHOPIFY_STORE_NAME` the one per-repo
value it preserves.
**And check for an existing `.github/workflows/lint.yml`** — a repo that hand-rolled its own would
be silently clobbered by the kit's; it is the one kit *workflow* name likely to already exist.

Expand Down
Loading