Skip to content

chore: fix drifted references and workflow schema gap#29

Merged
kyle-sexton merged 1 commit into
mainfrom
chore/hygiene-sweep-2026-07-20
Jul 20, 2026
Merged

chore: fix drifted references and workflow schema gap#29
kyle-sexton merged 1 commit into
mainfrom
chore/hygiene-sweep-2026-07-20

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

No related issue: proactive repo hygiene sweep.

Summary

Structure and factual-accuracy fixes across the locally-owned surface. The 7 upstream-managed files (.editorconfig, .gitattributes, .editorconfig-checker.json, .markdownlint-cli2.jsonc, _typos.toml, lychee.toml, .gitleaks.toml) were classified against standards/distribution/sync-manifest.yml and left untouched.

  • ci.yml — the workflow schema-validation step hand-enumerated three files. do-not-merge.yml and pr-issue-linkage.yml were added later in ci: add do-not-merge and pr-issue-linkage gate callers #25 without updating the list, so 2 of 5 workflows shipped unvalidated. Replaced with .github/workflows/*.yml.
  • PULL_REQUEST_TEMPLATE.md — claimed two forms were "the only two top-line forms the pr-issue-linkage gate accepts". False on both counts: the gate's keyword match is unanchored, and it accepts all nine GitHub closing-keyword spellings plus two no-issue markers. Now points at the gate's own failure output instead of restating its rules — restating is what let it drift.
  • pr-issue-linkage.yml — header comment named only one of the two accepted no-issue markers. Now defers to the reusable.
  • profile/README.md — listed 2 of 5 public repositories. Added standards and claude-code-plugins, both already described in the page's own prose.
  • .gitignore — comment attributed bin//obj/ to "the dotnet fixtures"; this repo contains no .NET files.

⚠️ One behavior-affecting change — please review deliberately

The ci.yml glob broadens what CI validates from 3 files to 5. Zero diff today is not zero behavior change: a schema-invalid do-not-merge.yml or pr-issue-linkage.yml previously passed and now fails, and future workflow files auto-enter validation.

Verified before applying: the check-jsonschema composite action documents glob support (action.yml:9) and deliberately leaves $FILES unquoted so globs expand (action.yml:70); all five workflows pass vendor.github-workflows at the pinned version today.

Known latent gap: the glob matches .yml only. A future .yaml workflow would be silently unvalidated — same as the old enumeration, so not a regression. The naive fix of adding a second *.yaml glob is wrong: the action sets no nullglob, so an unmatched pattern is passed through literally and crashes the tool. Correct fix routes upstream to ci-workflows; filed separately.

The issue-forms validation list stays enumerated on purpose — config.yml shares that directory and needs a different schema, so a glob there would be a bug.

Test plan

  • actionlint — clean
  • check-jsonschema vendor.github-workflows against all 5 workflows — ok, exit 0
  • markdownlint-cli2 v0.23.0 against repo config — 0 errors
  • lychee --offline — 21 links, 0 errors
  • typos, editorconfig-checker, gitleaks — clean
  • git diff --check — clean
  • Independent fresh-context review of the diff — no correctness, syntax, or undeclared-behavior defects

Related

  • Reinvented-wheel audit found no qualifying migrations beyond the glob above; do-not-merge and pr-issue-linkage were verified to have no native GitHub equivalent (full ruleset rule-type enum + changelog sweep), so both are correctly hand-rolled rather than reinvented.
  • Follow-up items routed to ci-workflows, github-iac, and standards are filed separately; none are branch-owned.

Repo hygiene sweep. Structure and factual-accuracy fixes, plus one
deliberately-accepted coverage change.

ci.yml: the workflow schema-validation step hand-enumerated three files.
do-not-merge.yml and pr-issue-linkage.yml were added later (#25) without
updating the list, so 2 of 5 workflows shipped unvalidated. Replaced with
a glob, which the check-jsonschema action documents and supports. This
broadens what CI validates from 3 files to 5 — all five pass the schema
today, so the gate is green now and the gap cannot silently reopen.

PULL_REQUEST_TEMPLATE.md: claimed two forms were "the only two top-line
forms the pr-issue-linkage gate accepts". Both counts were false — the
gate's keyword match is unanchored, and it accepts all nine GitHub
closing-keyword spellings plus two no-issue markers. Rewritten to point
at the gate's own failure output; restating its rules is what let the
description drift.

pr-issue-linkage.yml: header comment named only one of the two accepted
no-issue markers. Now defers to the reusable for the exact forms.

profile/README.md: listed 2 of 5 public repositories. Added standards and
claude-code-plugins, both already described in the page's own prose.

.gitignore: comment attributed bin/ and obj/ to "the dotnet fixtures";
this repo contains no .NET files.

The issue-forms validation list stays enumerated on purpose — config.yml
shares that directory and needs a different schema, so a glob there would
be a bug.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UmDSbhvfsnpL1DuTMjjJtP
@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Follow-ups from this sweep, all routed to the repo that owns the fix — none are branch-owned, so none block this PR:

ci-workflows

github-iac

  • melodic-software/github-iac#181 — native ruleset commit_message_pattern vs the pr-title workflow (Enterprise-gated, likely keep both).

standards

@kyle-sexton
kyle-sexton merged commit e3685f2 into main Jul 20, 2026
13 checks passed
@kyle-sexton
kyle-sexton deleted the chore/hygiene-sweep-2026-07-20 branch July 20, 2026 18:36
kyle-sexton added a commit that referenced this pull request Jul 20, 2026
)

Closes melodic-software/standards#213

## Summary

The `.gitignore` header called this a *"Language/framework-agnostic
base"* that *"language overlays (.NET, Python, …) extend with their own
ignores when adopted"* — framing that implies a shared baseline
distributed from `standards`.

**No such distribution exists.** `.gitignore` appears nowhere in
`standards/distribution/sync-manifest.yml`, for any component or any
target.

**Nor could it, in this shape.** Git has no include mechanism, so a
managed base plus a local overlay cannot coexist in one `.gitignore`.
That is exactly the partial ownership the distribution README rules out:
*"A component that needs a different destination or partial ownership is
the wrong component boundary and must be split first."* So the file
cannot become a managed component as designed, and the header should
stop implying it is one.

**It was never a real baseline in practice.** Of the 10 org repos
carrying a `.gitignore`, only this one and `dotfiles` used the "agnostic
base" framing — and those two had already diverged from each other (26
vs 33 lines). The other eight are entirely unique, ranging 7 to 821
lines.

## Test plan

- [x] Header comment only — **no ignore patterns changed**, so tracking
behavior is byte-for-byte identical.
- [x] `git status` clean against an unchanged working tree before and
after; no files newly ignored or un-ignored.
- [x] Verified `.gitignore` absent from `sync-manifest.yml` (`grep -c
gitignore` → 0).
- [x] Verified the header framing appears in only 2 of 10 org repos, and
that those 2 already diverge.

## Related

- The companion header in `melodic-software/dotfiles` is worse — it
explicitly attributes the base to `(melodic-software/standards)`, naming
a distribution source that does not distribute this file. Fixed in a
separate PR against that repo.
- The Node, Lefthook, and .NET sections are deliberately **kept**. They
guard tooling that can run against a local checkout regardless of what
source this repo tracks. Whether to prune them is a separate question,
not decided here.
- Surfaced by the repo hygiene sweep in #29.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kyle-sexton added a commit to melodic-software/ci-workflows that referenced this pull request Jul 20, 2026
…165)

## Summary

`.github/actions/check-jsonschema` documents `files` as accepting shell
globs and
deliberately leaves `$FILES` unquoted so they expand — but never set
`nullglob`, so a
pattern matching nothing was passed through literally and crashed the
tool with
`OSError`. That makes the documented glob support unsafe to use
defensively (the
`*.yml` + `*.yaml` case from melodic-software/.github#29).

Both halves of the fix land together, because `nullglob` **alone** would
convert a loud
crash into `check-jsonschema` being invoked with zero files — which
exits 0 and becomes a
**false-green CI lane**, strictly worse than the bug:

1. `shopt -s nullglob`, scoped to the expansion only (`shopt -u
nullglob` immediately
   after), capturing into a `targets` array.
2. A guard on the **total** expansion: if `targets` is empty the step
fails with its own
   message.

The call site now passes `"${targets[@]}"` (already expanded) rather
than re-expanding
`$FILES`, which also clears the pre-existing SC2086 on that line. The
`files` input
description gained one sentence stating the new contract.

### Two distinct failure paths

| Input | Message |
| --- | --- |
| `files` empty / whitespace-only (pre-existing guard, unchanged) |
`::error::files is required.` |
| `files` non-empty but expands to nothing (new) | `::error::files
expanded to no existing paths: <patterns>` |

Behavior deliberately **not** changed: a literal filename with no glob
metacharacters is
untouched by `nullglob`, so a non-existent literal still reaches the
tool and errors there
exactly as before.

## Verification

### 1. Before/after against the real tool, in this repo

The pre-fix block reproduces the issue's crash on the defensive pattern;
the fixed block
passes:

```text
--- REAL: the #162 defensive pattern (.yml + .yaml, repo has no .yaml)  [FIXED BLOCK]
ok -- validation done
EXIT=0
--- REAL: same pattern against the PRE-FIX block (reproduces the bug)
  File ".../check_jsonschema/cli/param_types.py", line 146, in __init__
    if "r" in mode and not stat.S_ISFIFO(os.stat(filename).st_mode):
                                         ~~~~~~~^^^^^^^^^^
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: '.github/workflows/*.yaml'
EXIT=1
```

Live regression cases — the three real `ci.yml` call sites, run with the
actual
`check-jsonschema@0.37.4` against this worktree:

```text
--- REAL: literal single file (ci.yml case 1)     files=.github/dependabot.yml
ok -- validation done
EXIT=0
--- REAL: workflows glob (ci.yml case 2)          files=.github/workflows/*.yml
ok -- validation done
EXIT=0
--- REAL: composite actions glob (ci.yml case 3)  files=.github/actions/*/action.yml
ok -- validation done
EXIT=0
```

### 2. Matrix over the modified shell logic

A throwaway harness extracts the Validate step's `run:` block
**verbatim** from
`action.yml` (byte-diffed against the file to prove it is not a
paraphrase), runs it under
the real `set -euo pipefail`, and stubs `uvx` with an arg-counter so the
number of file
arguments actually handed to the tool is observable. Fixture tree: two
`.yml` workflows,
zero `.yaml`.

```text
--- CASE: literal single file
    files=[.github/workflows/ci.yml]
    uvx-stub: invoked with 1 file arg(s): .github/workflows/ci.yml
    EXIT=0

--- CASE: multiple space-separated literals
    files=[.github/workflows/ci.yml .github/workflows/release.yml]
    uvx-stub: invoked with 2 file arg(s): .github/workflows/ci.yml .github/workflows/release.yml
    EXIT=0

--- CASE: glob matching several files
    files=[.github/workflows/*.yml]
    uvx-stub: invoked with 2 file arg(s): .github/workflows/ci.yml .github/workflows/release.yml
    EXIT=0

--- CASE: glob matching nothing
    files=[.github/workflows/*.yaml]
    ::error::files expanded to no existing paths: .github/workflows/*.yaml
    EXIT=1

--- CASE: mix: matching + non-matching glob
    files=[.github/workflows/*.yml .github/workflows/*.yaml]
    uvx-stub: invoked with 2 file arg(s): .github/workflows/ci.yml .github/workflows/release.yml
    EXIT=0

--- CASE: all-empty expansion (2 dud globs)
    files=[.github/workflows/*.yaml *.toml]
    ::error::files expanded to no existing paths: .github/workflows/*.yaml *.toml
    EXIT=1

--- CASE: empty input (pre-existing guard)
    files=[]
    ::error::files is required.
    EXIT=1

--- CASE: whitespace-only input
    files=[   ]
    ::error::files is required.
    EXIT=1

--- CASE: literal missing file (unchanged)
    files=[.github/workflows/nope.yml]
    uvx-stub: invoked with 1 file arg(s): .github/workflows/nope.yml
    EXIT=0
```

### 3. The false-green is demonstrated, not asserted

Same harness, with **only** the empty-expansion guard stripped out
(`nullglob` retained) —
i.e. what half 1 without half 2 would ship:

```text
=== FALSE-GREEN CONTROL: nullglob WITHOUT the empty guard ===
    uvx-stub: invoked with 0 file arg(s): <none>
    EXIT=0  <-- exit 0 with 0 files = the false green half-2 prevents
```

### 4. Static analysis

ShellCheck 0.11.0 (the version this repo pins) against the extracted
block, using the
repo's `.shellcheckrc`:

- **Before:** `SC2086` (info) on the unquoted `$FILES` at the call site,
plus two `SC2154`
  warnings.
- **After:** no `SC2086`, no `SC2206`. Only the same two `SC2154`
warnings
(`NO_CACHE`, `VERSION`), which are artifacts of extracting the block out
of its `env:`
  block — present identically before the change.

The `# shellcheck disable=SC2206` directive was proven load-bearing by
stripping it and
re-linting:

```text
In - line 23:
targets=($FILES)
         ^----^ SC2206 (warning): Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.
```

Also clean: `editorconfig-checker` (exit 0), `typos` (exit 0), and this
repo's own
`check-jsonschema` `vendor.github-actions` validation over
`.github/actions/*/action.yml`
including the edited file (exit 0).

## Blast radius

The composite is called by every repo in the constellation. Existing
callers pass plain
space-separated literal file lists **and** globs; both paths are covered
above and behave
identically to before. The only new failure mode is one that previously
either crashed
with `OSError` or (after half 1 alone) would have silently passed.

## Not verified here

`actionlint` does not lint composite `action.yml` files — passing the
file explicitly makes
it parse it as a workflow and emit `"jobs" section is missing` / `"on"
section is missing`.
This composite's `run:` block therefore has never been covered by the
repo's `actionlint`
job; the standalone ShellCheck run above is the equivalent check. Not
changed here — out of
scope for #162.

Closes #162

## Related

- melodic-software/.github#29 — the consumer hygiene sweep that surfaced
this; it wants
`files: .github/workflows/*.yml .github/workflows/*.yaml`, which this
makes safe.
- `.github/workflows/ci.yml` — the three in-repo call sites (one
literal, two globs) that
  serve as the live regression cases above.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01UmDSbhvfsnpL1DuTMjjJtP

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kyle-sexton added a commit to melodic-software/standards that referenced this pull request Jul 20, 2026
Closes #212

## Summary

The private-repo exclusion list named **4 of the org's 9** private
repositories. Missing: `itinerary-planner`, `knowledge-corpus`,
`medley-archive`, `melodic-main-archive`, `songwriting`.

A link to any of the five 404s in the online link lane for precisely the
reason the list exists to prevent — the calling repo's `GITHUB_TOKEN`
cannot read another private repo. Latent rather than breaking today,
since no tracked file currently links to them. The block's own comment
states the rule it drifted from: *"Keep in sync with actual visibility:
add newly created private repos here."*

`medley-archive` is ordered before `medley` in the alternation so the
longer name cannot be shadowed by a prefix match.

## Test plan

Verified empirically with `lychee --dump` over a fixture covering all 9
private repos plus `.git` and `github.com/ghraw` variants,
comparing old config against new.

- [x] **Old config leaked 8 private URLs:**

```
itinerary-planner, knowledge-corpus, medley-archive, melodic-main-archive,
songwriting, medley-archive.git,
github.com/ghraw/.../medley-archive/..., raw.../songwriting/...
```

- [x] **New config excludes all 9**, including the `.git` and `raw.`
variants.
- [x] **The 3 public repos still survive exclusion and stay checked** —
`standards`, `ci-workflows`, `.github` — confirming the change does not
over-exclude.
- [x] `medley` vs `medley-archive` disambiguation confirmed by the
fixture, not by reasoning about alternation order.
- [x] lefthook pre-commit: typos, gitleaks, editorconfig all pass.

## Related

- Follows the same maintenance pattern as #204 (`fix(lychee): drop
claude-code-plugins and standards from the private-repo exclusions`),
which moved entries the other direction when repos went public.
- Surfaced by a repo hygiene sweep of `melodic-software/.github`
(melodic-software/.github#29). Not fixable there — `lychee` is an
upstream-managed component, so the change belongs here and reaches
consumers through the reconciliation sync.
- Worth considering separately: this list is hand-maintained against a
queryable fact (`gh repo list --visibility private`), so it will drift
again. A generation or CI-check step would remove the class of problem
rather than this instance. Not in scope here.
kyle-sexton added a commit to melodic-software/ci-workflows that referenced this pull request Jul 20, 2026
…164)

## The issue's framing is stale — read this first

#163 was filed **leaning reject**, on the observation that the
aggregation block
appeared in only two repos (this one and `melodic-software/.github`).
That count
was wrong. The block is byte-identical in **seven**: `.github`,
`ci-runner`,
`ci-workflows`, `dotfiles`, `github-iac`, `provisioning`, `standards`.
At seven
call sites the "weak case" the issue argues against no longer holds, so
the
decision is to **adopt**. The issue body is not edited; this PR is the
documented
answer it asked for.

The issue's two reservations still stand as facts, and neither is fatal:

- **The `needs` list stays duplicated.** GitHub has no "all other jobs"
selector.
The composite owns the *semantics*, not the lane inventory — the `needs`
array
and the matching results string remain caller-owned. That is a real
limit on
how much this removes, not a reason to leave the semantics forked seven
ways.
- **It adds a dependency to the merge-gating job.** True, and it is why
this PR
adopts the composite **only here**. Consumers pin by SHA per the repo's
pin-everything rule; a same-repo caller references it by local path, so
the
gate resolves from the checkout it already has rather than over the
network.

## What this adds

`.github/actions/ci-status` — a composite taking the caller-built
results string
as one input. Semantics preserved exactly: `success` and `skipped` pass,
anything else fails with the original message naming the offending
result.

House style followed from `.github/actions/check-jsonschema`: `shell:
bash`,
`set -euo pipefail`, and the input passed via `env:` rather than
interpolated
into `run:`. The `env:` indirection matters specifically here — the
string is
built from `needs.*.result` expressions, and the expression-into-`run:`
shape is
the template-injection pattern this repo avoids everywhere else.

## Deliberate behavior change: empty input now fails closed

Verified baseline of the inline block:

```
OLD input=[] -> exit=0 out=All lanes passed or were skipped.
```

`read -ra` on an empty string yields an empty array, the loop body never
runs,
and the gate reports green. On the one job every merge depends on, a
results
string that came out empty means a miswired `needs` list or a typo'd
expression
— and the current block reports that as a pass.

The composite rejects it instead (`::error::results is required.`,
matching the
sibling composite's required-input idiom). This is the only intentional
divergence from the inline block; every non-empty input behaves
identically.

## Self-adoption

`ci-workflows`' own `ci.yml` `ci-status` job (27 lanes) now calls
`./.github/actions/ci-status`, matching the local-composite reference
pattern the
file already uses throughout. The job gains an `actions/checkout` step —
a local `./`
action needs the repo in the workspace, and this job previously had no
checkout.
Same pinned `actions/checkout@9c091bb…` + `persist-credentials: false`
as every
other lane.

The `needs` list and the results expression are unchanged, character for
character.

## Testing

Local matrix against the exact `run:` body extracted from the shipped
`action.yml` (not a retyped copy):

```
all-success              input=[success success success]
  exit=0
  out=All lanes passed or were skipped.

success+skipped          input=[success skipped success skipped]
  exit=0
  out=All lanes passed or were skipped.

one failure              input=[success skipped failure success]
  exit=1
  out=A lane did not pass (result: failure).

one cancelled            input=[success cancelled skipped]
  exit=1
  out=A lane did not pass (result: cancelled).

empty string             input=[]
  exit=1
  out=::error::results is required.

whitespace only          input=[   ]
  exit=1
  out=::error::results is required.
```

Also run locally, all clean:

- `actionlint .github/workflows/ci.yml` — clean
- `shellcheck --shell=bash` on the extracted composite body — clean
- `check-jsonschema --builtin-schema vendor.github-actions` on the new
  `action.yml` — `ok -- validation done`
- `markdownlint-cli2 README.md` — 0 errors

### The first CI run proved the failure path for real

The initial run's `ci-status` **failed, correctly**. `selector-contract`
failed,
and the composite caught it in the live 27-lane environment:

```
RESULTS: success success success success success success success success success
success success success success success success failure success success success
success success success success success success success success
A lane did not pass (result: failure).
```

That is the failure path exercised against 27 real `needs.*.result`
values —
better evidence than a green run alone would have been.

The `selector-contract` failure was caused by this PR and is now fixed.
`.github/scripts/go-quality.test.cjs` asserts that the go-quality lane's
result
actually reaches the gate, and pinned the literal `RESULTS:` env key.
Aggregation
moved to the composite's `results:` input at the same indent, so the
assertion
was updated to match the line it always meant. The test's intent is
unchanged;
`node --test .github/scripts/*.test.cjs` → **199 pass, 0 fail**.

## Scope

Only what #163 requires plus this repo's self-adoption. The other six
repos are
separate follow-up PRs — deliberately not touched, so the composite
proves itself
on one caller before it gates six more.

Closes #163

## Related

- melodic-software/.github#29 — the reinvented-wheel audit that surfaced
this
- `.github/actions/check-jsonschema` — the house-style precedent for
inputs,
  `env:` passing, and the required-input error idiom

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Jul 20, 2026
No related issue: rollout of the decision recorded in
melodic-software/ci-workflows#163, plus the pin bump that makes
melodic-software/ci-workflows#162 live here.

## Summary

Two changes to `ci.yml`, both about consuming `ci-workflows` composites.

**1. Adopt the `ci-status` composite.** The nine-line lane-aggregation
loop was duplicated byte-identically across seven repos. It now lives in
`ci-workflows` (melodic-software/ci-workflows#164) and this is one of
the six adopters.

**2. Bump the four `check-jsonschema` pins** to the same SHA, which
carries the `nullglob` fix from melodic-software/ci-workflows#165.

## ⚠️ The composite is NOT a like-for-like copy — it fixes two false
greens

Worth reviewing deliberately rather than as a mechanical extraction. The
inline block being replaced had two defects, both found by Codex review
on melodic-software/ci-workflows#164:

- `read -ra results <<< "$RESULTS"` consumed **only the first line**. A
multi-line results string left every lane after the first unchecked —
the gate reported success while a lane had failed.
- The empty guard trimmed spaces only, so newline-only or tab-only input
passed it, produced an empty array, skipped the loop, and reported
success.

Both were unreachable while the block was fed a single-line `${{ }}`
interpolation, and both become reachable once the input is an action
input. Reproduced against the old logic:

```
OLD  MULTILINE failure 2nd     EXIT=0  All lanes passed or were skipped.
OLD  MULTILINE failure last    EXIT=0  All lanes passed or were skipped.
OLD  newline only              EXIT=0  All lanes passed or were skipped.
OLD  tab only                  EXIT=0  All lanes passed or were skipped.
```

All four now exit 1. **Empty input also now fails closed** where it
previously passed — a deliberate behavior change: a gate with nothing to
aggregate is a miswired `needs` list, not a pass.

## Why the pin bump matters here specifically

#29 replaced this repo's hand-enumerated workflow list with
`.github/workflows/*.yml`. The `nullglob` fix guards a fully-empty
expansion so it fails loudly instead of validating nothing — that guard
is what keeps the glob safe if a future rename ever leaves it matching
zero files.

## Test plan

- [x] `actionlint` — clean
- [x] `check-jsonschema` `vendor.github-workflows` against all 5
workflows — `ok`, exit 0
- [x] Composite behavior verified across 13 cases before adoption
(single-line, multi-line, tab-separated, cancelled, skipped, empty,
whitespace-only)
- [x] CI on this PR exercises the composite against this repo's real
8-lane `needs` list

## Related

- melodic-software/ci-workflows#164 — the composite, and the dogfooding
adoption in `ci-workflows` itself
- melodic-software/ci-workflows#165 — the `nullglob` fix now pinned here
- melodic-software/ci-workflows#167 — composite `run:` blocks are not
ShellCheck-covered, which is why both bugs above reached review rather
than CI
- Other `ci-workflows` composite pins deliberately stay at `1d3762c`;
Dependabot owns those bumps, and moving all of them here would pull ten
days of unrelated change into a targeted fix.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant