docs: recommend the @v1 release tag for reusable-workflow consumers #12

Merged
steve merged 2 commits from docs/recommend-v1 into main 2026-06-28 04:17:19 +00:00
Owner

Makes the public contract match how the fleet now pins. The example stub + README pointed at @main/@<sha>; update to recommend @v1 — gadfly's curated release tag, re-moved on deliberate releases so central swarm tuning propagates without per-consumer re-pinning. A full @<sha> is still offered for an immutable pin; @main is discouraged (moves on every push).

  • examples/reusable.yml: uses: …@main@v1 + updated pin comments.
  • README.md: pin guidance now covers the reusable workflow ref (@v1 / @<sha>), not just the image :vN tag.

Docs-only. Advisory-only invariant unchanged.

🤖 Generated with Claude Code

Makes the public contract match how the fleet now pins. The example stub + README pointed at `@main`/`@<sha>`; update to recommend **`@v1`** — gadfly's curated release tag, re-moved on deliberate releases so central swarm tuning propagates without per-consumer re-pinning. A full `@<sha>` is still offered for an immutable pin; `@main` is discouraged (moves on every push). - `examples/reusable.yml`: `uses: …@main` → `@v1` + updated pin comments. - `README.md`: pin guidance now covers the reusable workflow ref (`@v1` / `@<sha>`), not just the image `:vN` tag. Docs-only. Advisory-only invariant unchanged. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
steve added 1 commit 2026-06-28 04:10:16 +00:00
docs: recommend the @v1 release tag for reusable-workflow consumers
Adversarial Review (Gadfly) / review (pull_request) Successful in 3m48s
6f85b9341f
The example stub + README pinned guidance pointed at @main/@<sha>; update them to
recommend @v1 — gadfly's curated release tag that's moved on deliberate releases
so central swarm tuning propagates without per-consumer re-pinning (full @<sha>
still offered for an immutable pin; @main discouraged).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

🪰 Gadfly — live review status

6/6 reviewers finished · updated 2026-06-28 04:14:05Z

claude-code/opus · claude-code — done

  • security — No material issues found
  • correctness — Minor issues
  • maintainability — Minor issues
  • performance — No material issues found
  • error-handling — No material issues found

claude-code/opus:max · claude-code — done

  • security — No material issues found
  • correctness — No material issues found
  • maintainability — Minor issues
  • performance — No material issues found
  • error-handling — No material issues found

claude-code/sonnet · claude-code — done

  • security — Minor issues
  • correctness — Blocking issues found
  • maintainability — Minor issues
  • performance — No material issues found
  • error-handling — No material issues found

deepseek-v4-pro:cloud · ollama-cloud — done

  • security — No material issues found
  • correctness — Minor issues
  • maintainability — Minor issues
  • performance — No material issues found
  • error-handling — No material issues found

glm-5.2:cloud · ollama-cloud — done

  • security — No material issues found
  • correctness — Minor issues
  • maintainability — No material issues found
  • performance — No material issues found
  • error-handling — No material issues found

minimax-m3:cloud · ollama-cloud — done

  • security — No material issues found
  • correctness — Blocking issues found
  • maintainability — Minor issues
  • performance — No material issues found
  • error-handling — No material issues found

Live status board. Findings are posted in each model's own comment. Advisory only — does not block merge.

<!-- gadfly-status-board --> ## 🪰 Gadfly — live review status 6/6 reviewers finished · updated 2026-06-28 04:14:05Z #### `claude-code/opus` · claude-code — ✅ done - ✅ **security** — No material issues found - ✅ **correctness** — Minor issues - ✅ **maintainability** — Minor issues - ✅ **performance** — No material issues found - ✅ **error-handling** — No material issues found #### `claude-code/opus:max` · claude-code — ✅ done - ✅ **security** — No material issues found - ✅ **correctness** — No material issues found - ✅ **maintainability** — Minor issues - ✅ **performance** — No material issues found - ✅ **error-handling** — No material issues found #### `claude-code/sonnet` · claude-code — ✅ done - ✅ **security** — Minor issues - ✅ **correctness** — Blocking issues found - ✅ **maintainability** — Minor issues - ✅ **performance** — No material issues found - ✅ **error-handling** — No material issues found #### `deepseek-v4-pro:cloud` · ollama-cloud — ✅ done - ✅ **security** — No material issues found - ✅ **correctness** — Minor issues - ✅ **maintainability** — Minor issues - ✅ **performance** — No material issues found - ✅ **error-handling** — No material issues found #### `glm-5.2:cloud` · ollama-cloud — ✅ done - ✅ **security** — No material issues found - ✅ **correctness** — Minor issues - ✅ **maintainability** — No material issues found - ✅ **performance** — No material issues found - ✅ **error-handling** — No material issues found #### `minimax-m3:cloud` · ollama-cloud — ✅ done - ✅ **security** — No material issues found - ✅ **correctness** — Blocking issues found - ✅ **maintainability** — Minor issues - ✅ **performance** — No material issues found - ✅ **error-handling** — No material issues found <sub>Live status board. Findings are posted in each model's own comment. Advisory only — does not block merge.</sub>

🪰 Gadfly review — deepseek-v4-pro:cloud (ollama-cloud)

Verdict: Minor issues — 5 reviewers: security, correctness, maintainability, performance, error-handling

🔒 Security — No material issues found

Verdict: No material issues found

This is a docs-only change that steers consumers from @main (moves on every push — highest supply-chain risk) toward either @v1 (curated release tag, moves only on deliberate releases) or @<sha> (immutable). From a security perspective, this is a net improvement: it reduces the window during which a compromised push to main would silently propagate into every consumer's workflow with their forwarded secrets.

  • The tradeoffs are transparently documented: @v1 auto-updates on releases (convenience, central tuning propagates) vs. @<sha> (immutable, no surprise changes). Both are strictly better than @main, which the diff now explicitly discourages.
  • No injection, credential leakage, authz bypass, or other security regression is introduced — the change touches only advisory prose and a comment in an example stub.

One minor observation (not a security issue, but noted for completeness): the reusable workflow's own doc comment at .gitea/workflows/review-reusable.yml:28 still says "Consumers should likewise pin uses: ...@<sha> (not @main)" without mentioning @v1. That file wasn't in this diff, so it's outside scope, but it's now slightly out of step with the new guidance.

🎯 Correctness — Minor issues

Now I have all the information I need. Let me evaluate each finding:

Finding 1 (@v1 tag may not exist): The draft reviewer explicitly labels this as "Unverified" and acknowledges it's a shallow clone where the tag could exist on the remote. I confirmed there is no local v1 tag. Since the reviewer themselves cannot confirm it, and I also cannot positively confirm it (the tag's absence in a shallow clone of a feature branch proves nothing), this finding must be dropped per the instructions: "DROP the finding if you cannot confirm it."

Finding 2 (docstring drift): I confirmed that .gitea/workflows/review-reusable.yml was not modified in this diff. Its header comment at line 9 still documents the consumer call as @<sha> only, and lines 28-29 still say "Consumers should likewise pin uses: ...@<sha> (not @main)." Meanwhile, the PR updates examples/reusable.yml and README.md to recommend @v1. This is a real inconsistency — the reusable workflow's own docstring contradicts the new guidance. Kept.


Verdict: Minor issues

  • Docstring drift in the reusable workflow itself. The reusable workflow's own header comment at .gitea/workflows/review-reusable.yml:9 still documents the consumer call as @<sha> only:
    #       uses: steve/gadfly/.gitea/workflows/review-reusable.yml@<sha>
    
    And lines 28–29 reinforce that with "Consumers should likewise pin uses: ...@<sha> (not @main)." This file is not in the diff, but it's the canonical documentation inside the workflow being referenced. Now the example stub says @v1 while the reusable workflow's own docstring says @<sha> with no mention of @v1. A consumer who opens the reusable workflow to understand their pin options will see only the @<sha> recommendation — contradicting the new guidance. Not a runtime bug, but a correctness-of-documentation inconsistency that undermines the PR's purpose.
🧹 Code cleanliness & maintainability — Minor issues

Verdict: Minor issues

  • .gitea/workflows/review-reusable.yml:9,28-29 — stale pin guidance in the reusable workflow's own header comment. The PR updates consumer-facing docs (examples/reusable.yml, README.md) to recommend @v1 as the primary ref, but the reusable workflow's own docstring still says uses: ...@<sha> (line 9) and "Consumers should likewise pin uses: ...@<sha> (not @main)" (lines 28-29) with no mention of @v1. A maintainer reading this file gets different guidance than a consumer reading the examples. Over time these two sources of truth will drift further. (Verified by reading the file at lines 1-30.)

    Fix: Update lines 9 and 28-29 to match the new guidance — e.g., @v1 (or @<sha>) and mention the curated-tag approach, so the reusable workflow's own documentation stays in sync with the consumer-facing examples.

Performance — No material issues found

Verdict: No material issues found

This is a docs-only change — it updates comments in examples/reusable.yml and guidance in README.md to recommend @v1 (a curated release tag) over @main for the reusable workflow ref. There is no code, no logic, no runtime path, and therefore nothing to evaluate through the performance lens. The change has zero impact on allocations, queries, loops, blocking calls, or any other performance characteristic.

🧯 Error handling & edge cases — No material issues found

Verdict: No material issues found

This is a docs-only change — it updates comments in examples/reusable.yml and prose in README.md. There are no code paths, no new functions, no error returns, no panics, and no data handling introduced. The error-handling & edge-cases lens (ignored errors, missing cleanup/rollback, panics on bad input, nil/empty/zero/negative/overflow/off-by-one) has nothing to evaluate here.

The one thing that brushes against "edge case" territory — whether the @v1 tag actually exists on the repo right now (if it doesn't, consumers following the new guidance would get an immediate workflow-resolution failure) — is a deployment-coordination concern, not an error-handling defect in the diff. I can't verify tag existence with the available file-reading tools, but even if the tag were missing, that's a release-process gap, not something the diff's code/configuration mishandles.

Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 2m 13s

<!-- gadfly-review:ollama:deepseek-v4-pro:cloud --> ### 🪰 Gadfly review — `deepseek-v4-pro:cloud` (ollama-cloud) **Verdict: Minor issues** — 5 reviewers: security, correctness, maintainability, performance, error-handling <details><summary><b>🔒 Security</b> — No material issues found</summary> ## Verdict: No material issues found This is a docs-only change that steers consumers from `@main` (moves on every push — highest supply-chain risk) toward either `@v1` (curated release tag, moves only on deliberate releases) or `@<sha>` (immutable). From a security perspective, this is a net improvement: it reduces the window during which a compromised push to `main` would silently propagate into every consumer's workflow with their forwarded secrets. - The tradeoffs are transparently documented: `@v1` auto-updates on releases (convenience, central tuning propagates) vs. `@<sha>` (immutable, no surprise changes). Both are strictly better than `@main`, which the diff now explicitly discourages. - No injection, credential leakage, authz bypass, or other security regression is introduced — the change touches only advisory prose and a comment in an example stub. One minor observation (not a security issue, but noted for completeness): the reusable workflow's own doc comment at `.gitea/workflows/review-reusable.yml:28` still says "Consumers should likewise pin `uses: ...@<sha>` (not @main)" without mentioning `@v1`. That file wasn't in this diff, so it's outside scope, but it's now slightly out of step with the new guidance. </details> <details><summary><b>🎯 Correctness</b> — Minor issues</summary> Now I have all the information I need. Let me evaluate each finding: **Finding 1 (`@v1` tag may not exist):** The draft reviewer explicitly labels this as "Unverified" and acknowledges it's a shallow clone where the tag could exist on the remote. I confirmed there is no local `v1` tag. Since the reviewer themselves cannot confirm it, and I also cannot positively confirm it (the tag's absence in a shallow clone of a feature branch proves nothing), this finding must be **dropped** per the instructions: "DROP the finding if you cannot confirm it." **Finding 2 (docstring drift):** I confirmed that `.gitea/workflows/review-reusable.yml` was not modified in this diff. Its header comment at line 9 still documents the consumer call as `@<sha>` only, and lines 28-29 still say "Consumers should likewise pin `uses: ...@<sha>` (not @main)." Meanwhile, the PR updates `examples/reusable.yml` and `README.md` to recommend `@v1`. This is a real inconsistency — the reusable workflow's own docstring contradicts the new guidance. **Kept.** --- ## Verdict: Minor issues - **Docstring drift in the reusable workflow itself.** The reusable workflow's own header comment at `.gitea/workflows/review-reusable.yml:9` still documents the consumer call as `@<sha>` only: ``` # uses: steve/gadfly/.gitea/workflows/review-reusable.yml@<sha> ``` And lines 28–29 reinforce that with "Consumers should likewise pin `uses: ...@<sha>` (not @main)." This file is not in the diff, but it's the canonical documentation inside the workflow being referenced. Now the example stub says `@v1` while the reusable workflow's own docstring says `@<sha>` with no mention of `@v1`. A consumer who opens the reusable workflow to understand their pin options will see only the `@<sha>` recommendation — contradicting the new guidance. Not a runtime bug, but a correctness-of-documentation inconsistency that undermines the PR's purpose. </details> <details><summary><b>🧹 Code cleanliness & maintainability</b> — Minor issues</summary> ## Verdict: Minor issues - **`.gitea/workflows/review-reusable.yml:9,28-29` — stale pin guidance in the reusable workflow's own header comment.** The PR updates consumer-facing docs (`examples/reusable.yml`, `README.md`) to recommend `@v1` as the primary ref, but the reusable workflow's own docstring still says `uses: ...@<sha>` (line 9) and "Consumers should likewise pin `uses: ...@<sha>` (not @main)" (lines 28-29) with no mention of `@v1`. A maintainer reading this file gets different guidance than a consumer reading the examples. Over time these two sources of truth will drift further. *(Verified by reading the file at lines 1-30.)* **Fix:** Update lines 9 and 28-29 to match the new guidance — e.g., `@v1` (or `@<sha>`) and mention the curated-tag approach, so the reusable workflow's own documentation stays in sync with the consumer-facing examples. </details> <details><summary><b>⚡ Performance</b> — No material issues found</summary> ## Verdict: No material issues found This is a docs-only change — it updates comments in `examples/reusable.yml` and guidance in `README.md` to recommend `@v1` (a curated release tag) over `@main` for the reusable workflow ref. There is no code, no logic, no runtime path, and therefore nothing to evaluate through the performance lens. The change has zero impact on allocations, queries, loops, blocking calls, or any other performance characteristic. </details> <details><summary><b>🧯 Error handling & edge cases</b> — No material issues found</summary> ## Verdict: No material issues found This is a docs-only change — it updates comments in `examples/reusable.yml` and prose in `README.md`. There are no code paths, no new functions, no error returns, no panics, and no data handling introduced. The error-handling & edge-cases lens (ignored errors, missing cleanup/rollback, panics on bad input, nil/empty/zero/negative/overflow/off-by-one) has nothing to evaluate here. The one thing that brushes against "edge case" territory — whether the `@v1` tag actually exists on the repo right now (if it doesn't, consumers following the new guidance would get an immediate workflow-resolution failure) — is a deployment-coordination concern, not an error-handling defect in the diff. I can't verify tag existence with the available file-reading tools, but even if the tag were missing, that's a release-process gap, not something the diff's code/configuration mishandles. </details> <sub>Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 2m 13s</sub>

🪰 Gadfly review — glm-5.2:cloud (ollama-cloud)

Verdict: Minor issues — 5 reviewers: security, correctness, maintainability, performance, error-handling

🔒 Security — No material issues found

VERDICT: No material issues found

Reviewed through the security lens. This is a docs-only change adjusting pin guidance for the reusable-workflow uses: ref.

  • examples/reusable.yml:54 now pins @v1 instead of @main, and the comment block (:17-20, :52-53) accurately explains the security trade-off: @v1 is a curated tag moved only on deliberate releases (so central tuning propagates), @<sha> is offered for an immutable pin, and @main is explicitly discouraged because it moves on every push and "would change what runs with your forwarded secrets." The least-privilege secrets-forwarding guidance (:14-16, :58-62) and the comment-trigger actor gate (:49-51, github.actor == 'your-username') are untouched and remain sound.
  • README.md:315-318 mirrors the same guidance consistently. No secret leakage, injection, authn/authz, or unsafe-input handling is introduced — the only tainted surface (forwarded secrets to a third-party workflow) is already addressed by the explicit secrets: block advice, which this PR preserves.

The change is a net security improvement (moving the recommended example off the highest-churn mutable ref while still documenting the immutable option). Nothing in my lane to flag.

🎯 Correctness — Minor issues

The finding is confirmed. Lines 9 and 28-29 of .gitea/workflows/review-reusable.yml still recommend @<sha> with no mention of @v1, directly contradicting the updated README and examples/reusable.yml guidance.

VERDICT: Minor issues

  • .gitea/workflows/review-reusable.yml:9 and :28-29 — The PR rewrites the pin guidance in README.md and examples/reusable.yml to recommend @v1 as the primary ref (with @<sha> as the immutable alternative, avoid @main), but the reusable workflow's own header comments — consumer-facing documentation embedded in the file consumers actually point at — were not updated. Line 9's example still shows ...review-reusable.yml@<sha> with no mention of @v1, and lines 28–29 explicitly state "Consumers should likewise pin uses: ...@<sha> (not @main)", framing @<sha> as the recommendation. This now directly contradicts the new README/example guidance (@v1 first, @<sha> as the immutable alternative). A consumer reading the workflow file they're subscribing to gets the old, conflicting advice. Suggested fix: update those two comment spots to match the new @v1-first / @<sha>-immutable / avoid-@main ordering. (Note: the v1 git tag's existence could not be confirmed with read-only tools; worth verifying it exists before/with merge so the example's @v1 ref resolves.)
🧹 Code cleanliness & maintainability — No material issues found

No material issues found.

The diff is docs/comment-only and cleanly updates the pin guidance to @v1 consistently across both files. The example file (examples/reusable.yml) and README prose both use the same framing (@v1 curated release tag → auto-updating stability; @<sha> → immutable pin; avoid @main), so the duplicated messaging stays consistent rather than drifting. No dead code, naming, or structural concerns introduced.

Performance — No material issues found

No material issues found.

This is a docs-only change (comments in examples/reusable.yml and prose in README.md) updating recommended pin references (@main@v1). It touches no runtime code, queries, loops, allocations, or hot paths — there is nothing to evaluate through the performance lens.

🧯 Error handling & edge cases — No material issues found

No material issues found

This is a docs-only change: it rewrites comments in examples/reusable.yml (lines 17-20, 52-54) and prose in README.md (lines 315-318) to recommend @v1 over @main. No executable code, logic, error-handling, input parsing, or control flow is touched.

Through the error-handling / edge-case lens specifically:

  • No new unhappy paths are introduced — the only edited runtime-adjacent line is the uses: ref (@main@v1), which is a ref string, not logic. A missing/non-existent @v1 tag would surface as a Gitea Actions checkout/reusable-resolution failure at job start (same failure mode as any bad ref), not a swallowed error or panic in this repo's code.
  • No nil/empty/zero/overflow/boundary concerns apply to ref strings or documentation prose.

Nothing in my lane to flag.

Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 1m 10s

<!-- gadfly-review:ollama:glm-5.2:cloud --> ### 🪰 Gadfly review — `glm-5.2:cloud` (ollama-cloud) **Verdict: Minor issues** — 5 reviewers: security, correctness, maintainability, performance, error-handling <details><summary><b>🔒 Security</b> — No material issues found</summary> **VERDICT: No material issues found** Reviewed through the security lens. This is a docs-only change adjusting pin guidance for the reusable-workflow `uses:` ref. - `examples/reusable.yml:54` now pins `@v1` instead of `@main`, and the comment block (`:17-20`, `:52-53`) accurately explains the security trade-off: `@v1` is a curated tag moved only on deliberate releases (so central tuning propagates), `@<sha>` is offered for an immutable pin, and `@main` is explicitly discouraged because it moves on every push and "would change what runs with your forwarded secrets." The least-privilege secrets-forwarding guidance (`:14-16`, `:58-62`) and the comment-trigger actor gate (`:49-51`, `github.actor == 'your-username'`) are untouched and remain sound. - `README.md:315-318` mirrors the same guidance consistently. No secret leakage, injection, authn/authz, or unsafe-input handling is introduced — the only tainted surface (forwarded secrets to a third-party workflow) is already addressed by the explicit `secrets:` block advice, which this PR preserves. The change is a net security improvement (moving the recommended example off the highest-churn mutable ref while still documenting the immutable option). Nothing in my lane to flag. </details> <details><summary><b>🎯 Correctness</b> — Minor issues</summary> The finding is confirmed. Lines 9 and 28-29 of `.gitea/workflows/review-reusable.yml` still recommend `@<sha>` with no mention of `@v1`, directly contradicting the updated README and `examples/reusable.yml` guidance. VERDICT: Minor issues - `.gitea/workflows/review-reusable.yml:9` and `:28-29` — The PR rewrites the pin guidance in `README.md` and `examples/reusable.yml` to recommend `@v1` as the primary ref (with `@<sha>` as the immutable alternative, avoid `@main`), but the reusable workflow's **own header comments** — consumer-facing documentation embedded in the file consumers actually point at — were not updated. Line 9's example still shows `...review-reusable.yml@<sha>` with no mention of `@v1`, and lines 28–29 explicitly state *"Consumers should likewise pin `uses: ...@<sha>` (not @main)"*, framing `@<sha>` as the recommendation. This now directly contradicts the new README/example guidance (`@v1` first, `@<sha>` as the immutable alternative). A consumer reading the workflow file they're subscribing to gets the old, conflicting advice. Suggested fix: update those two comment spots to match the new `@v1`-first / `@<sha>`-immutable / avoid-`@main` ordering. (Note: the `v1` git tag's existence could not be confirmed with read-only tools; worth verifying it exists before/with merge so the example's `@v1` ref resolves.) </details> <details><summary><b>🧹 Code cleanliness & maintainability</b> — No material issues found</summary> No material issues found. The diff is docs/comment-only and cleanly updates the pin guidance to `@v1` consistently across both files. The example file (`examples/reusable.yml`) and README prose both use the same framing (`@v1` curated release tag → auto-updating stability; `@<sha>` → immutable pin; avoid `@main`), so the duplicated messaging stays consistent rather than drifting. No dead code, naming, or structural concerns introduced. </details> <details><summary><b>⚡ Performance</b> — No material issues found</summary> No material issues found. This is a docs-only change (comments in `examples/reusable.yml` and prose in `README.md`) updating recommended pin references (`@main` → `@v1`). It touches no runtime code, queries, loops, allocations, or hot paths — there is nothing to evaluate through the performance lens. </details> <details><summary><b>🧯 Error handling & edge cases</b> — No material issues found</summary> No material issues found This is a docs-only change: it rewrites **comments** in `examples/reusable.yml` (lines 17-20, 52-54) and prose in `README.md` (lines 315-318) to recommend `@v1` over `@main`. No executable code, logic, error-handling, input parsing, or control flow is touched. Through the error-handling / edge-case lens specifically: - No new unhappy paths are introduced — the only edited runtime-adjacent line is the `uses:` ref (`@main` → `@v1`), which is a ref string, not logic. A missing/non-existent `@v1` tag would surface as a Gitea Actions checkout/reusable-resolution failure at job start (same failure mode as any bad ref), not a swallowed error or panic in this repo's code. - No nil/empty/zero/overflow/boundary concerns apply to ref strings or documentation prose. Nothing in my lane to flag. </details> <sub>Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 1m 10s</sub>

🪰 Gadfly review — claude-code/sonnet (claude-code)

Verdict: Blocking issues found — 5 reviewers: security, correctness, maintainability, performance, error-handling

🔒 Security — Minor issues

The finding is confirmed. Lines 28-29 of review-reusable.yml still say pin uses: ...@<sha> (not @main), which directly contradicts the new guidance in examples/reusable.yml that recommends @v1 as the primary recommendation. The second finding (mutable tag trust model) is a design-level observation about the PR's documented intent — the PR description acknowledges the tradeoff — and there is no code to confirm or deny it against; it's a documentation quality concern the draft labels as intentional.


Minor issues

  • review-reusable.yml still contradicts the new guidance (review-reusable.yml:28-29):
    The reusable workflow's own header comment still says:

    "Consumers should likewise pin uses: ...@<sha> (not @main) so a push to this repo can't silently change the code that runs with their forwarded secrets."

    The updated example stub now defaults to @v1 (mutable tag), but this authoritative comment in the reusable workflow was not updated. A security-aware consumer reading review-reusable.yml directly will get the opposite recommendation from what the example stub models — the two pieces of guidance now contradict each other.

    Suggested fix: Update review-reusable.yml lines 28–29 to align with the new guidance (e.g., mention @v1 as the recommended starting point and @<sha> for an immutable pin).

🎯 Correctness — Blocking issues found

The git repository has no tags at all — git tag -l returns empty, and packed-refs contains only the remote branch ref. The build-image workflow (lines 73–74) confirms it publishes Docker image tags in response to a pushed v* git tag, but it does not create the git tag itself. The diff in examples/reusable.yml:54 changes @main to @v1, and README.md instructs consumers to pin review-reusable.yml@v1. The finding is confirmed.


Blocking issues found

  • @v1 tag does not exist — examples/reusable.yml:54 / README.md:315

    No v1 git tag has been pushed to this repository (git tag -l returns empty; .git/packed-refs contains only the remote branch ref for docs/recommend-v1). The diff changes uses: …@main to uses: steve/gadfly/.gitea/workflows/review-reusable.yml@v1 and updates the README to tell consumers to pin review-reusable.yml@v1, but in Gitea Actions the @ref in a uses: directive resolves to a live git ref. A consumer who follows this guidance right now will get a workflow resolution failure — the ref simply doesn't exist.

    The build-image workflow (.gitea/workflows/build-image.yml:21,73-74) publishes Docker image tags when a v* git tag is pushed; it does not create the git tag itself. Git tags must be pushed separately via git tag v1 && git push origin v1.

    Fix: Push a v1 git tag to the repository (or the release cut that creates it) before — or atomically with — merging this PR. Without that tag, any consumer following the updated docs or example stub will have a broken workflow.

🧹 Code cleanliness & maintainability — Minor issues

Verdict: Minor issues

  • README:315 — terminology mismatch. The PR introduces the term "full-stub consumers" in the Release section (line 315), but the README's own intro (lines 40–44) refers to the same adversarial-review.yml path as "the full self-contained adversarial-review.yml". A reader scanning only the Release section encounters "full-stub consumers" without a prior definition tying it to adversarial-review.yml; the intro's "full self-contained" phrasing is the more anchored reference. Fix: match the intro's wording — e.g. "Pin full-self-contained-stub consumers…" or append (\adversarial-review.yml`)` inline. Verified against README lines 39–46 and 313–318.

  • Slightly inconsistent phrasing for the same concept across files. @v1 is described three ways:

    • README line 317: "a curated tag moved on releases"
    • examples/reusable.yml line 18: "a curated pointer moved on deliberate releases"
    • examples/reusable.yml line 52: "curated release tag (auto-updates on releases)"

    "Tag" vs "pointer," "moved on releases" vs "moved on deliberate releases" vs "auto-updates on releases" — not a runtime issue, but when the wording drifts across three spots for the same concept, the next editor won't know which phrasing is authoritative and will need to update all three again. Picking one phrasing and using it consistently reduces future churn. Verified by reading both files.

Neither finding is blocking. The docs are broadly coherent and the actual @v1 pin on examples/reusable.yml:54 is correctly placed.

Performance — No material issues found

No material issues found.

This is a docs-only change (README prose and a comment + uses: ref in an example YAML). There is no executable code, no queries, no allocations, no loops, and no hot paths touched. Nothing to evaluate through a performance lens.

🧯 Error handling & edge cases — No material issues found

No material issues found

This is a pure documentation change — updated prose in README.md and revised comments plus a single uses: ref string in examples/reusable.yml. There are no code paths, error returns, input handling, or runtime logic of any kind introduced or modified. My lens (error handling & edge cases) has nothing to evaluate here.

Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 3m 30s

<!-- gadfly-review:ollama:claude-code/sonnet --> ### 🪰 Gadfly review — `claude-code/sonnet` (claude-code) **Verdict: Blocking issues found** — 5 reviewers: security, correctness, maintainability, performance, error-handling <details><summary><b>🔒 Security</b> — Minor issues</summary> The finding is confirmed. Lines 28-29 of `review-reusable.yml` still say `pin uses: ...@<sha> (not @main)`, which directly contradicts the new guidance in `examples/reusable.yml` that recommends `@v1` as the primary recommendation. The second finding (mutable tag trust model) is a design-level observation about the PR's documented intent — the PR description acknowledges the tradeoff — and there is no code to confirm or deny it against; it's a documentation quality concern the draft labels as intentional. --- **Minor issues** - **`review-reusable.yml` still contradicts the new guidance** (`review-reusable.yml:28-29`): The reusable workflow's own header comment still says: > "Consumers should likewise pin `uses: ...@<sha>` (not `@main`) so a push to this repo can't silently change the code that runs with their forwarded secrets." The updated example stub now defaults to `@v1` (mutable tag), but this authoritative comment in the reusable workflow was not updated. A security-aware consumer reading `review-reusable.yml` directly will get the opposite recommendation from what the example stub models — the two pieces of guidance now contradict each other. **Suggested fix**: Update `review-reusable.yml` lines 28–29 to align with the new guidance (e.g., mention `@v1` as the recommended starting point and `@<sha>` for an immutable pin). </details> <details><summary><b>🎯 Correctness</b> — Blocking issues found</summary> The git repository has no tags at all — `git tag -l` returns empty, and `packed-refs` contains only the remote branch ref. The build-image workflow (lines 73–74) confirms it publishes *Docker image* tags in response to a pushed `v*` git tag, but it does not create the git tag itself. The diff in `examples/reusable.yml:54` changes `@main` to `@v1`, and `README.md` instructs consumers to pin `review-reusable.yml@v1`. The finding is confirmed. --- **Blocking issues found** - **`@v1` tag does not exist — `examples/reusable.yml:54` / `README.md:315`** No `v1` git tag has been pushed to this repository (`git tag -l` returns empty; `.git/packed-refs` contains only the remote branch ref for `docs/recommend-v1`). The diff changes `uses: …@main` to `uses: steve/gadfly/.gitea/workflows/review-reusable.yml@v1` and updates the README to tell consumers to pin `review-reusable.yml@v1`, but in Gitea Actions the `@ref` in a `uses:` directive resolves to a live git ref. A consumer who follows this guidance right now will get a workflow resolution failure — the ref simply doesn't exist. The build-image workflow (`.gitea/workflows/build-image.yml:21,73-74`) publishes *Docker image* tags when a `v*` git tag is pushed; it does not create the git tag itself. Git tags must be pushed separately via `git tag v1 && git push origin v1`. **Fix:** Push a `v1` git tag to the repository (or the release cut that creates it) before — or atomically with — merging this PR. Without that tag, any consumer following the updated docs or example stub will have a broken workflow. </details> <details><summary><b>🧹 Code cleanliness & maintainability</b> — Minor issues</summary> **Verdict: Minor issues** - **README:315 — terminology mismatch.** The PR introduces the term "full-stub consumers" in the Release section (line 315), but the README's own intro (lines 40–44) refers to the same `adversarial-review.yml` path as **"the full self-contained `adversarial-review.yml`"**. A reader scanning only the Release section encounters "full-stub consumers" without a prior definition tying it to `adversarial-review.yml`; the intro's "full self-contained" phrasing is the more anchored reference. Fix: match the intro's wording — e.g. `"Pin full-self-contained-stub consumers…"` or append `(\`adversarial-review.yml\`)` inline. Verified against README lines 39–46 and 313–318. - **Slightly inconsistent phrasing for the same concept across files.** `@v1` is described three ways: - README line 317: "a curated tag moved on releases" - `examples/reusable.yml` line 18: "a curated pointer moved on deliberate releases" - `examples/reusable.yml` line 52: "curated release tag (auto-updates on releases)" "Tag" vs "pointer," "moved on releases" vs "moved on deliberate releases" vs "auto-updates on releases" — not a runtime issue, but when the wording drifts across three spots for the same concept, the next editor won't know which phrasing is authoritative and will need to update all three again. Picking one phrasing and using it consistently reduces future churn. Verified by reading both files. Neither finding is blocking. The docs are broadly coherent and the actual `@v1` pin on `examples/reusable.yml:54` is correctly placed. </details> <details><summary><b>⚡ Performance</b> — No material issues found</summary> No material issues found. This is a docs-only change (README prose and a comment + `uses:` ref in an example YAML). There is no executable code, no queries, no allocations, no loops, and no hot paths touched. Nothing to evaluate through a performance lens. </details> <details><summary><b>🧯 Error handling & edge cases</b> — No material issues found</summary> **No material issues found** This is a pure documentation change — updated prose in `README.md` and revised comments plus a single `uses:` ref string in `examples/reusable.yml`. There are no code paths, error returns, input handling, or runtime logic of any kind introduced or modified. My lens (error handling & edge cases) has nothing to evaluate here. </details> <sub>Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 3m 30s</sub>

🪰 Gadfly review — claude-code/opus:max (claude-code)

Verdict: Minor issues — 5 reviewers: security, correctness, maintainability, performance, error-handling

🔒 Security — No material issues found

VERDICT: No material issues found

This is a docs-only change to supply-chain pinning guidance, which is squarely in scope for the security lens — so I checked it on the merits rather than waving it through.

  • examples/reusable.yml:54 and the surrounding comment (:17-20, :52-53), plus README.md:315-318 — the change swaps the recommended reusable-workflow ref from @main to @v1. Verified by reading both files at the PR state. Security-relevant facts:
    • A reusable workflow runs with the consumer's forwarded secrets, so the immutability of its uses: ref is a genuine supply-chain control. @v1 is a mutable tag ("re-moved on deliberate releases"), meaning a moved/compromised v1 would execute new code against forwarded secrets.
    • However, this is a net improvement, not a regression: the prior recommendation was @main, which mutates on every push (strictly larger attack surface). @v1 moves only on deliberate releases.
    • The guidance honestly discloses the tradeoff and offers the immutable @<sha> pin for consumers who want it, and explicitly discourages @main. This mirrors standard practice (actions/checkout@v4).
    • The least-privilege secret guidance (explicit secrets: forwarding over secrets: inherit) is preserved (:14-16, :55-62).

No injection, secret leakage, authz, or untrusted-data handling is introduced or weakened. Nothing material in my lane.

One note, not a finding: a careless copy-paste consumer gets a mutable pin by default — but that's already mitigated by the explicit inline comment recommending @<sha>, and it's a security upgrade over the previous @main default.

🎯 Correctness — No material issues found

I've verified the change against the actual repo. My investigation is complete.

VERDICT: No material issues found

This is a docs-only change. Through the Correctness lens, the factual claims hold up against how the system actually works, and the two edited files are internally consistent.

What I verified:

  • Moving-@v1 claim is consistent with the release model. README:317 and examples/reusable.yml:52 describe @v1 as a curated tag "moved on releases" so swarm tuning propagates. I confirmed the mechanism: review-reusable.yml:93 hardcodes the image at :sha-c342bdb and its header (:26-27) says that sha is "bumped per Gadfly release." So re-pointing the v1 git tag to a newer commit does propagate a newer pinned image — the auto-update story is coherent, not contradictory. A force-moved v* tag also re-triggers build-image.yml (:19-21), republishing :v1/:latest, so the image and workflow-ref stories line up.
  • :vN image vs @v1 workflow-ref guidance is accurate. build-image.yml:73-74 publishes :${GITHUB_REF_NAME} (+:latest) on a v* tag push, matching README:315's :vN advice.
  • No stale/contradictory refs left behind. Grepped README, examples/, and CLAUDE.md: every consumer-facing ref now recommends @v1/@<sha> and discourages @main; README:41 uses a neutral @… placeholder. No leftover @main recommendation that would contradict the new guidance.
  • owner/repo path unchanged. steve/gadfly/.gitea/workflows/review-reusable.yml matches the registry path gitea.stevedudenhoeffer.com/steve/gadfly; only the ref suffix changed.

One caveat I could not verify (flagging, not asserting as a bug):

  • Existence of the v1 tag. git tag -l returns nothing at this checkout, and I was denied network access to git ls-remote, so I cannot confirm a v1 tag actually exists on the remote yet. If the release process cuts only semver tags (e.g. v1.0.0) and never pushes/moves a bare v1, then a consumer copy-pasting examples/reusable.yml:54 (...review-reusable.yml@v1) would hit a workflow-resolution failure, and :v1 image pins would also break. This is a release-process/sequencing concern external to the diff text — worth a one-line confirmation from the author that the v1 tag is (or will be) published before/with these docs, but it is not a logic defect in the change itself.

Outside my lens: none worth raising.

🧹 Code cleanliness & maintainability — Minor issues

Both findings verify against the code. review-reusable.yml:9 still shows …@<sha> and :28 still says pin uses: ...@ (not @main) with no mention of @v1, while README.md:317-318 and examples/reusable.yml now lead with @v1. And git tag -l is empty — no v1 tag exists.

VERDICT: Minor issues

Finding — stale duplicate of the pin guidance left un-updated (@<sha>/@main, no @v1)
.gitea/workflows/review-reusable.yml:9 and :28

The "how to pin the reusable" advice exists in three consumer-facing places. This PR updated two of them (README.md:315-318, examples/reusable.yml:17-19,52-54) to recommend @v1, but the third copy — the worked consumer-stub example and pin note in the reusable workflow's own header — still reads:

  • line 9: uses: steve/gadfly/.gitea/workflows/review-reusable.yml@<sha>
  • line 28: Consumers should likewise pin uses: ...@ (not @main)…

So the contract now gives inconsistent guidance depending on which file a consumer opens: README/example say "use @v1, sha is the immutable alternative," while review-reusable.yml's header still presents @<sha> as the recommendation and never mentions @v1. CLAUDE.md's maintenance rule ("the example workflows are the contract users rely on — stale docs are a bug") applies directly here.

  • Fix (low-churn): update review-reusable.yml:9 to …@v1 and reword :28 to mirror the new phrasing ("pin @v1 for auto-updating stability, or @<sha> for an immutable pin; avoid @main"). Keeps the three copies in sync.

Note the duplication itself is the root maintainability smell — the same paragraph is now hand-maintained in three spots and has already drifted once. Not worth refactoring docs into a single source here, but the fix above should bring all three back into agreement in this same change.

Outside my lens (flagging because it's potentially blocking): git tag -l returns no tags — there is currently no v1 tag (or any tag) in the repo. If the curated @v1 ref isn't actually created/moved as part of this release, every doc now points consumers at a ref that won't resolve. That's a correctness/release-process concern for another reviewer, not a cleanliness one.

Nothing else in my lens: the wording changes in the two edited files are clear, consistent with each other, and follow the surrounding comment style.

Performance — No material issues found

VERDICT: No material issues found

This is a documentation-only change — README.md pin guidance and examples/reusable.yml comments/ref, swapping @main@v1. There is no code, query, loop, allocation, or hot path touched, so there is nothing for the performance lens to evaluate.

  • No runtime behavior changes: both files are docs/config-comment edits; the only functional line is the uses: workflow ref, which affects which image/workflow consumers pin to, not execution efficiency. Verified by reading the full diff — both hunks are comment text and prose.

Nothing in my lane to flag here.

🧯 Error handling & edge cases — No material issues found

VERDICT: No material issues found

This is a docs-only change — prose in README.md and YAML comments plus a single uses: ref string (@main@v1) in examples/reusable.yml. There is no executable code, no control flow, and therefore no error paths, cleanup/rollback, boundary conditions, nil/empty handling, or overflow surface for my lens to evaluate.

I confirmed from the diff that the only non-comment change is the workflow ref tag in the uses: line; everything else is comment/prose. Nothing in the error-handling & edge-case lens is materially wrong here.

  • Outside my lens: the docs now recommend consumers pin to review-reusable.yml@v1. Whether that tag actually exists in the gadfly repo is a real correctness concern (a dangling ref would break every consumer's workflow resolution), but that belongs to the correctness lens, not mine.

Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 2m 20s

<!-- gadfly-review:ollama:claude-code/opus:max --> ### 🪰 Gadfly review — `claude-code/opus:max` (claude-code) **Verdict: Minor issues** — 5 reviewers: security, correctness, maintainability, performance, error-handling <details><summary><b>🔒 Security</b> — No material issues found</summary> **VERDICT: No material issues found** This is a docs-only change to supply-chain pinning guidance, which is squarely in scope for the security lens — so I checked it on the merits rather than waving it through. - `examples/reusable.yml:54` and the surrounding comment (`:17-20`, `:52-53`), plus `README.md:315-318` — the change swaps the recommended reusable-workflow ref from `@main` to `@v1`. Verified by reading both files at the PR state. Security-relevant facts: - A reusable workflow runs **with the consumer's forwarded secrets**, so the immutability of its `uses:` ref is a genuine supply-chain control. `@v1` is a *mutable* tag ("re-moved on deliberate releases"), meaning a moved/compromised `v1` would execute new code against forwarded secrets. - However, this is a **net improvement, not a regression**: the prior recommendation was `@main`, which mutates on *every* push (strictly larger attack surface). `@v1` moves only on deliberate releases. - The guidance honestly discloses the tradeoff and offers the immutable `@<sha>` pin for consumers who want it, and explicitly discourages `@main`. This mirrors standard practice (`actions/checkout@v4`). - The least-privilege secret guidance (explicit `secrets:` forwarding over `secrets: inherit`) is preserved (`:14-16`, `:55-62`). No injection, secret leakage, authz, or untrusted-data handling is introduced or weakened. Nothing material in my lane. One note, not a finding: a careless copy-paste consumer gets a mutable pin by default — but that's already mitigated by the explicit inline comment recommending `@<sha>`, and it's a security upgrade over the previous `@main` default. </details> <details><summary><b>🎯 Correctness</b> — No material issues found</summary> I've verified the change against the actual repo. My investigation is complete. ## VERDICT: No material issues found This is a docs-only change. Through the **Correctness lens**, the factual claims hold up against how the system actually works, and the two edited files are internally consistent. What I verified: - **Moving-`@v1` claim is consistent with the release model.** README:317 and `examples/reusable.yml:52` describe `@v1` as a curated tag "moved on releases" so swarm tuning propagates. I confirmed the mechanism: `review-reusable.yml:93` hardcodes the image at `:sha-c342bdb` and its header (`:26-27`) says that sha is "bumped per Gadfly release." So re-pointing the `v1` git tag to a newer commit does propagate a newer pinned image — the auto-update story is coherent, not contradictory. A force-moved `v*` tag also re-triggers `build-image.yml` (`:19-21`), republishing `:v1`/`:latest`, so the image and workflow-ref stories line up. - **`:vN` image vs `@v1` workflow-ref guidance is accurate.** `build-image.yml:73-74` publishes `:${GITHUB_REF_NAME}` (+`:latest`) on a `v*` tag push, matching README:315's `:vN` advice. - **No stale/contradictory refs left behind.** Grepped README, `examples/`, and CLAUDE.md: every consumer-facing ref now recommends `@v1`/`@<sha>` and discourages `@main`; README:41 uses a neutral `@…` placeholder. No leftover `@main` recommendation that would contradict the new guidance. - **owner/repo path unchanged.** `steve/gadfly/.gitea/workflows/review-reusable.yml` matches the registry path `gitea.stevedudenhoeffer.com/steve/gadfly`; only the ref suffix changed. One caveat I could **not** verify (flagging, not asserting as a bug): - **Existence of the `v1` tag.** `git tag -l` returns nothing at this checkout, and I was denied network access to `git ls-remote`, so I cannot confirm a `v1` tag actually exists on the remote yet. If the release process cuts only semver tags (e.g. `v1.0.0`) and never pushes/moves a bare `v1`, then a consumer copy-pasting `examples/reusable.yml:54` (`...review-reusable.yml@v1`) would hit a workflow-resolution failure, and `:v1` image pins would also break. This is a release-process/sequencing concern external to the diff text — worth a one-line confirmation from the author that the `v1` tag is (or will be) published before/with these docs, but it is not a logic defect in the change itself. Outside my lens: none worth raising. </details> <details><summary><b>🧹 Code cleanliness & maintainability</b> — Minor issues</summary> Both findings verify against the code. `review-reusable.yml:9` still shows `…@<sha>` and `:28` still says `pin `uses: ...@<sha>` (not @main)` with no mention of `@v1`, while `README.md:317-318` and `examples/reusable.yml` now lead with `@v1`. And `git tag -l` is empty — no `v1` tag exists. ## VERDICT: Minor issues **Finding — stale duplicate of the pin guidance left un-updated (`@<sha>`/`@main`, no `@v1`)** `.gitea/workflows/review-reusable.yml:9` and `:28` The "how to pin the reusable" advice exists in **three** consumer-facing places. This PR updated two of them (`README.md:315-318`, `examples/reusable.yml:17-19,52-54`) to recommend `@v1`, but the third copy — the worked consumer-stub example and pin note in the reusable workflow's own header — still reads: - line 9: `uses: steve/gadfly/.gitea/workflows/review-reusable.yml@<sha>` - line 28: `Consumers should likewise pin `uses: ...@<sha>` (not @main)…` So the contract now gives **inconsistent guidance depending on which file a consumer opens**: README/example say "use `@v1`, sha is the immutable alternative," while `review-reusable.yml`'s header still presents `@<sha>` as the recommendation and never mentions `@v1`. CLAUDE.md's maintenance rule ("the example workflows are the contract users rely on — stale docs are a bug") applies directly here. - *Fix (low-churn):* update `review-reusable.yml:9` to `…@v1` and reword `:28` to mirror the new phrasing ("pin `@v1` for auto-updating stability, or `@<sha>` for an immutable pin; avoid `@main`"). Keeps the three copies in sync. Note the duplication itself is the root maintainability smell — the same paragraph is now hand-maintained in three spots and has already drifted once. Not worth refactoring docs into a single source here, but the fix above should bring all three back into agreement in this same change. **Outside my lens (flagging because it's potentially blocking):** `git tag -l` returns no tags — there is currently no `v1` tag (or any tag) in the repo. If the curated `@v1` ref isn't actually created/moved as part of this release, every doc now points consumers at a ref that won't resolve. That's a correctness/release-process concern for another reviewer, not a cleanliness one. Nothing else in my lens: the wording changes in the two edited files are clear, consistent with each other, and follow the surrounding comment style. </details> <details><summary><b>⚡ Performance</b> — No material issues found</summary> **VERDICT: No material issues found** This is a documentation-only change — `README.md` pin guidance and `examples/reusable.yml` comments/ref, swapping `@main` → `@v1`. There is no code, query, loop, allocation, or hot path touched, so there is nothing for the performance lens to evaluate. - No runtime behavior changes: both files are docs/config-comment edits; the only functional line is the `uses:` workflow ref, which affects *which* image/workflow consumers pin to, not execution efficiency. Verified by reading the full diff — both hunks are comment text and prose. Nothing in my lane to flag here. </details> <details><summary><b>🧯 Error handling & edge cases</b> — No material issues found</summary> **VERDICT: No material issues found** This is a docs-only change — prose in `README.md` and YAML comments plus a single `uses:` ref string (`@main` → `@v1`) in `examples/reusable.yml`. There is no executable code, no control flow, and therefore no error paths, cleanup/rollback, boundary conditions, nil/empty handling, or overflow surface for my lens to evaluate. I confirmed from the diff that the only non-comment change is the workflow ref tag in the `uses:` line; everything else is comment/prose. Nothing in the error-handling & edge-case lens is materially wrong here. - Outside my lens: the docs now recommend consumers pin to `review-reusable.yml@v1`. Whether that tag actually exists in the gadfly repo is a real correctness concern (a dangling ref would break every consumer's workflow resolution), but that belongs to the correctness lens, not mine. </details> <sub>Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 2m 20s</sub>

🪰 Gadfly review — claude-code/opus (claude-code)

Verdict: Minor issues — 5 reviewers: security, correctness, maintainability, performance, error-handling

🔒 Security — No material issues found

VERDICT: No material issues found

I reviewed this through the security (supply-chain) lens, since the only thing a docs-only change to a pin recommendation can affect is what code runs with a consumer's forwarded secrets. I read both edited files in full (examples/reusable.yml:14-54, README.md:313-318) to confirm the diff matches the checked-out state.

What I checked and why it's not a finding:

  • Recommending a movable @v1 ref over an immutable @<sha> (examples/reusable.yml:52-54, README.md:316-318). This is the one real security-relevant trade-off: @v1 is re-pointed on releases, so whoever controls the gadfly repo can change the code that executes with the consumer's forwarded provider keys / GITEA_TOKEN — exactly the risk the old @<sha>-immutable wording warned about. However, the new text discloses this accurately rather than hiding it: it explains @v1 "moves on releases / deliberate releases," still documents @<sha> as the immutable option, and explicitly discourages the worst case @main ("moves on every push and would change what runs with your forwarded secrets"). This mirrors the project's already-accepted posture for the image :vN tag (also movable). It's an informed, disclosed product trade-off, not an insecure default introduced silently.

  • Least-privilege secret guidance preserved (examples/reusable.yml:14-20, 55-62). The edit left the "forward ONLY what the reviewer needs / prefer explicit over secrets: inherit" guidance and the commented-out optional secrets intact. No widening of secret exposure.

No injection, authz, SSRF, deserialization, validation, or credential-leak surface is touched — this is comment/prose only and the binary, scripts, and workflows are unchanged.

🎯 Correctness — Minor issues

I've verified both findings. The v1 tag does exist on the remote (refs/tags/v122aff85), so Finding 1 is contradicted by the actual repo state and must be dropped. Finding 2's factual basis is confirmed — review-reusable.yml lines 9 and 28–29 still reference only @<sha> and don't mention @v1 — though its "contradiction" framing is overstated (the header recommends @<sha>, which the new guidance still endorses, and warns against @main, which it also still endorses).

VERDICT: Minor issues

This is a docs-only change. The factual claims hold up against the code; one surviving consistency gap remains.

Findings (Correctness lens)

  • .gitea/workflows/review-reusable.yml:28-29 (and the example at :9) still tell consumers only to pin @<sha>, never mentioning the newly-recommended @v1. The PR updated README.md and examples/reusable.yml to recommend review-reusable.yml@v1 (curated release tag) as the primary option for reusable-workflow consumers, but the reusable workflow's own subscription instructions — a place a consumer reads to learn how to pin — still say only "Consumers should likewise pin uses: ...@<sha> (not @main)". This isn't a hard contradiction (@<sha> remains a valid form in the new guidance, and both discourage @main), but it's a missed spot: the now-preferred @v1 option isn't surfaced where consumers look. A one-block update there to mention @v1 would keep the guidance consistent. Confirmed by reading the file; minor docs-consistency item.
🧹 Code cleanliness & maintainability — Minor issues

I verified both findings against the actual repo.

Finding 1 (review-reusable.yml:9, :28): Confirmed. Line 9 still shows ...review-reusable.yml@<sha> as the canonical usage example, and line 28 still reads "Consumers should likewise pin uses: ...@<sha> (not @main)". Neither mentions @v1, while this PR makes @v1 the primary recommendation in README.md and examples/reusable.yml. The inconsistency across the three copies of consumer-facing pin guidance is real.

Finding 2 (@v1 may not resolve): Cannot positively confirm. git tag -l returns no tags in this checkout, but the draft itself flags this as unverified and "likely just unfetched tags," and absence of tags locally does not prove v1 is unpublished. Dropping per the gate rule (keep only what I can confirm).


VERDICT: Minor issues

  • .gitea/workflows/review-reusable.yml:9 and :28Stale/inconsistent pin guidance left behind. This PR updates the @v1 recommendation in README.md and examples/reusable.yml, but the reusable workflow's own header doc comments still say to pin @<sha> and "(not @main)" with no mention of @v1. Line 9's canonical usage example shows ...review-reusable.yml@<sha>, and line 28 says "Consumers should likewise pin uses: ...@<sha> (not @main)". After this change the public pin guidance now disagrees across three copies of the same advice. CLAUDE.md treats consumer-facing docs as "the contract users rely on — stale docs are a bug," so this is a real (if minor) maintainability gap. Fix: update lines 9 and 28 to match the new @v1-primary / @<sha>-immutable / avoid-@main framing (or replace the duplicated prose with a single pointer to the README section so it can't drift again).

The two files actually touched (README.md, examples/reusable.yml) are internally consistent and read cleanly; the wording change is well-scoped and low-churn.

Performance — No material issues found

VERDICT: No material issues found

This PR changes only README.md (pin-guidance prose) and examples/reusable.yml (comments + the uses: ref @main@v1). There is no executable code, no data path, no loops, queries, or allocations in the diff — nothing for a performance lens to evaluate.

  • examples/reusable.yml:55 / README.md:315: the only functional change is the workflow ref consumers pin to; it has zero runtime-performance dimension (it selects which version of the reusable workflow is fetched, not how much work it does).

Nothing in my lens is materially wrong.

🧯 Error handling & edge cases — No material issues found

The change touches only README.md and examples/reusable.yml, and within those only prose and YAML comments — no executable code, no scripts, no entrypoint.sh/Go logic. There are no error paths, no inputs being parsed, no cleanup/rollback, and no edge cases introduced by this diff.

VERDICT: No material issues found

  • This is a docs-only PR (README pin guidance + example stub comments/uses: ref). Through the error-handling & edge-cases lens there is nothing to scrutinize — no swallowed errors, no nil/empty/zero/overflow/boundary surfaces, no unhappy paths added. Verified by reading the full diff: the only functional line changed is the uses: workflow ref in examples/reusable.yml:54 (@main@v1), which is consumer-side YAML, not a code path Gadfly executes.

  • Outside my lens: the PR leans on a @v1 tag existing and being maintained as a "re-moved on releases" pointer; I could not confirm any v* tag exists in this repo (git tag -l returned empty) — but tag/release accuracy is a correctness/docs-validity concern for another lens, not error handling.

Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 3m 4s

<!-- gadfly-review:ollama:claude-code/opus --> ### 🪰 Gadfly review — `claude-code/opus` (claude-code) **Verdict: Minor issues** — 5 reviewers: security, correctness, maintainability, performance, error-handling <details><summary><b>🔒 Security</b> — No material issues found</summary> **VERDICT: No material issues found** I reviewed this through the security (supply-chain) lens, since the only thing a docs-only change to a pin recommendation can affect is what code runs with a consumer's forwarded secrets. I read both edited files in full (`examples/reusable.yml:14-54`, `README.md:313-318`) to confirm the diff matches the checked-out state. What I checked and why it's not a finding: - **Recommending a movable `@v1` ref over an immutable `@<sha>`** (`examples/reusable.yml:52-54`, `README.md:316-318`). This is the one real security-relevant trade-off: `@v1` is re-pointed on releases, so whoever controls the gadfly repo can change the code that executes with the consumer's forwarded provider keys / `GITEA_TOKEN` — exactly the risk the old `@<sha>`-immutable wording warned about. However, the new text **discloses this accurately** rather than hiding it: it explains `@v1` "moves on releases / deliberate releases," still documents `@<sha>` as the immutable option, and explicitly discourages the worst case `@main` ("moves on every push and would change what runs with your forwarded secrets"). This mirrors the project's already-accepted posture for the image `:vN` tag (also movable). It's an informed, disclosed product trade-off, not an insecure default introduced silently. - **Least-privilege secret guidance preserved** (`examples/reusable.yml:14-20, 55-62`). The edit left the "forward ONLY what the reviewer needs / prefer explicit over `secrets: inherit`" guidance and the commented-out optional secrets intact. No widening of secret exposure. No injection, authz, SSRF, deserialization, validation, or credential-leak surface is touched — this is comment/prose only and the binary, scripts, and workflows are unchanged. </details> <details><summary><b>🎯 Correctness</b> — Minor issues</summary> I've verified both findings. The `v1` tag **does exist** on the remote (`refs/tags/v1` → `22aff85`), so Finding 1 is contradicted by the actual repo state and must be dropped. Finding 2's factual basis is confirmed — `review-reusable.yml` lines 9 and 28–29 still reference only `@<sha>` and don't mention `@v1` — though its "contradiction" framing is overstated (the header recommends `@<sha>`, which the new guidance still endorses, and warns against `@main`, which it also still endorses). ## VERDICT: Minor issues This is a docs-only change. The factual claims hold up against the code; one surviving consistency gap remains. ### Findings (Correctness lens) - **`.gitea/workflows/review-reusable.yml:28-29` (and the example at `:9`) still tell consumers only to pin `@<sha>`, never mentioning the newly-recommended `@v1`.** The PR updated `README.md` and `examples/reusable.yml` to recommend `review-reusable.yml@v1` (curated release tag) as the primary option for reusable-workflow consumers, but the reusable workflow's own subscription instructions — a place a consumer reads to learn how to pin — still say only *"Consumers should likewise pin `uses: ...@<sha>` (not @main)"*. This isn't a hard contradiction (`@<sha>` remains a valid form in the new guidance, and both discourage `@main`), but it's a missed spot: the now-preferred `@v1` option isn't surfaced where consumers look. A one-block update there to mention `@v1` would keep the guidance consistent. *Confirmed by reading the file; minor docs-consistency item.* </details> <details><summary><b>🧹 Code cleanliness & maintainability</b> — Minor issues</summary> I verified both findings against the actual repo. **Finding 1** (review-reusable.yml:9, :28): Confirmed. Line 9 still shows `...review-reusable.yml@<sha>` as the canonical usage example, and line 28 still reads "Consumers should likewise pin `uses: ...@<sha>` (not @main)". Neither mentions `@v1`, while this PR makes `@v1` the primary recommendation in `README.md` and `examples/reusable.yml`. The inconsistency across the three copies of consumer-facing pin guidance is real. **Finding 2** (`@v1` may not resolve): Cannot positively confirm. `git tag -l` returns no tags in this checkout, but the draft itself flags this as unverified and "likely just unfetched tags," and absence of tags locally does not prove `v1` is unpublished. Dropping per the gate rule (keep only what I can confirm). --- **VERDICT: Minor issues** - `.gitea/workflows/review-reusable.yml:9` and `:28` — **Stale/inconsistent pin guidance left behind.** This PR updates the `@v1` recommendation in `README.md` and `examples/reusable.yml`, but the reusable workflow's *own* header doc comments still say to pin `@<sha>` and "(not @main)" with no mention of `@v1`. Line 9's canonical usage example shows `...review-reusable.yml@<sha>`, and line 28 says *"Consumers should likewise pin `uses: ...@<sha>` (not @main)"*. After this change the public pin guidance now disagrees across three copies of the same advice. CLAUDE.md treats consumer-facing docs as "the contract users rely on — stale docs are a bug," so this is a real (if minor) maintainability gap. Fix: update lines 9 and 28 to match the new `@v1`-primary / `@<sha>`-immutable / avoid-`@main` framing (or replace the duplicated prose with a single pointer to the README section so it can't drift again). The two files actually touched (`README.md`, `examples/reusable.yml`) are internally consistent and read cleanly; the wording change is well-scoped and low-churn. </details> <details><summary><b>⚡ Performance</b> — No material issues found</summary> **VERDICT: No material issues found** This PR changes only `README.md` (pin-guidance prose) and `examples/reusable.yml` (comments + the `uses:` ref `@main` → `@v1`). There is no executable code, no data path, no loops, queries, or allocations in the diff — nothing for a performance lens to evaluate. - `examples/reusable.yml:55` / `README.md:315`: the only functional change is the workflow ref consumers pin to; it has zero runtime-performance dimension (it selects which version of the reusable workflow is fetched, not how much work it does). Nothing in my lens is materially wrong. </details> <details><summary><b>🧯 Error handling & edge cases</b> — No material issues found</summary> The change touches only `README.md` and `examples/reusable.yml`, and within those only prose and YAML comments — no executable code, no scripts, no `entrypoint.sh`/Go logic. There are no error paths, no inputs being parsed, no cleanup/rollback, and no edge cases introduced by this diff. **VERDICT: No material issues found** - This is a docs-only PR (README pin guidance + example stub comments/`uses:` ref). Through the error-handling & edge-cases lens there is nothing to scrutinize — no swallowed errors, no nil/empty/zero/overflow/boundary surfaces, no unhappy paths added. Verified by reading the full diff: the only functional line changed is the `uses:` workflow ref in `examples/reusable.yml:54` (`@main` → `@v1`), which is consumer-side YAML, not a code path Gadfly executes. - *Outside my lens:* the PR leans on a `@v1` tag existing and being maintained as a "re-moved on releases" pointer; I could not confirm any `v*` tag exists in this repo (`git tag -l` returned empty) — but tag/release accuracy is a correctness/docs-validity concern for another lens, not error handling. </details> <sub>Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 3m 4s</sub>

🪰 Gadfly review — minimax-m3:cloud (ollama-cloud)

Verdict: Blocking issues found — 5 reviewers: security, correctness, maintainability, performance, error-handling

🔒 Security — No material issues found

Looking at this change through the 🔒 Security lens specifically.

The change is documentation-only — it updates pinning guidance from @main/@<sha> to @v1/@<sha> for reusable-workflow consumers. Security-relevant aspects to check:

  1. Secret forwarding surface — the comment correctly still warns about secrets: inherit handing over every repo secret; explicit forwarding is still recommended. The new guidance doesn't relax this.

  2. Tag mutability (@v1 vs @main vs @<sha>) — this is genuinely the security-relevant tradeoff, and the new comment explicitly:

    • Discourages @main (moves on every push — could change what runs against forwarded secrets without consumer action).
    • Offers @v1 as a curated tag "moved on deliberate releases" — less mutable than @main (only moves on tagged releases), but still mutable.
    • Offers full @<sha> as the immutable option.

    From a security perspective, @v1 is strictly better than @main (smaller attack window — attacker needs to land a v* tag push, not any main push) but strictly worse than @<sha> (which the comment also offers). The text is honest about this: "curated pointer moved on deliberate releases" vs "immutable pin." No claim that @v1 equals @<sha>.

  3. Permissions blockpermissions: stays at the existing least-privilege (contents: read, issues: write, pull-requests: write); unchanged.

  4. Comment-author gateissue_comment still gated to your-username; unchanged.

  5. No new injected input, no new deserialization, no new SSRF surface — purely a comment/ref change.

One minor observation: the new @v1 recommendation nudges consumers toward a mutable tag. A security-strict reviewer might prefer the PR to lead with @<sha> and mention @v1 as a convenience option, since silent movement of what runs against forwarded secrets is the exact threat the original @main-warning called out — and @v1 reintroduces a (smaller) version of it. But the comment does flag this honestly ("curated … moved on deliberate releases"), and @<sha> is still offered side-by-side. This is a recommendation/tone call, not a gap; I'll note it but not block on it.

No material security issues. The diff actually improves the security posture of the recommended default (smaller mutation window than @main) while preserving the immutable @<sha> escape hatch and the explicit-secrets warning.

VERDICT: No material issues found

  • No authn/authz, injection, SSRF, deserialization, or secret-handling regressions in the change.
  • permissions: block, secrets: explicit-forwarding guidance, and the actor gate on issue_comment are all unchanged.
  • The new pin guidance (@v1 over @main) reduces — not increases — the window in which an upstream push can silently change what runs against the consumer's forwarded secrets, while still documenting @<sha> as the immutable option. Verified by reading examples/reusable.yml:14–20,52–54 and README.md:313–318.
🎯 Correctness — Blocking issues found

VERDICT: Blocking issues found

  • examples/reusable.yml:54 / README.md:317 — the advertised @v1 mechanism does not exist in this repo. The PR's whole pitch is that @v1 is "gadfly's curated release tag, re-moved on deliberate releases so central swarm tuning propagates without per-consumer re-pinning." But the only release automation in the repo is .gitea/workflows/build-image.yml, which publishes container image tags (:v1, :latest, :sha-<short>) to gitea.stevedudenhoeffer.com/steve/gadfly — it never touches a git ref. Grep across the repo for any release script, tag-moving workflow, or git push --force ... v1 step returns nothing (scripts/ has only run.sh, status-board.sh, system-prompt.txt; .gitea/workflows/ has only build-image.yml, review-reusable.yml, adversarial-review.yml). So a consumer who follows the new advice and pins uses: steve/gadfly/.gitea/workflows/review-reusable.yml@v1 will get a workflow_call resolve failure unless a human manually git tag v1 <sha> && git push --force origin v1 for every release. Until the PR also adds the release-time automation (or at least an explicit scripts/release.sh + a release workflow that force-moves the git v1 tag on v* tag pushes), the new recommendation is a footgun: the default examples/reusable.yml will not run out of the box. Fix: add the missing automation in the same change (e.g. a scripts/release.sh invoked by a release.yml workflow on push: tags: ['v*'] that force-moves the git v1 ref to the new commit, mirroring how build-image.yml re-tags :latest), or hold this docs change until that exists.

  • .gitea/workflows/review-reusable.yml:9 and :28 — internal doc is now stale and contradicts the new recommendation. The reusable workflow's own header still tells consumers to pin uses: ...@<sha> (line 9: uses: steve/gadfly/.gitea/workflows/review-reusable.yml@<sha>) and the closing paragraph (line 28) still says "Consumers should likewise pin uses: ...@<sha> (not @main)" — without mentioning the @v1 option the freshly-updated README/reusable.yml now steer consumers toward. CLAUDE.md's own maintenance rule is "the README and examples/ … MUST be reflected … in the same change — stale docs are a bug." Three-doc rule, not two. Verified by reading .gitea/workflows/review-reusable.yml:1-30 and grepping the repo for @<sha> / @v1 / @main (hits in README.md, examples/reusable.yml, and .gitea/workflows/review-reusable.yml only). Fix: update the two @<sha> mentions in this file's header comment to the same @v1 (with @<sha> offered as the alternative) so all consumer-facing docs agree.

🧹 Code cleanliness & maintainability — Minor issues

VERDICT: Minor issues

  • README.md:315 — "full-stub consumers" is a newly coined compound that's never defined and only used once. examples/reusable.yml:1 calls its stub "SLIM consumer stub" and .gitea/workflows/review-reusable.yml:23 points consumers at "the full stub in adversarial-review.yml", so the established vocabulary is "slim" vs. "full". Hyphenating to "full-stub" reads as a new term and mildly obscures which of the two stubs is meant for the :vN advice. Suggest restructuring the sentence (e.g. "Pin the full stub to a :vN image tag for stability…") rather than introducing "full-stub".

  • Terminology drift between the two surfaces: README.md:317 calls @v1 "a curated tag moved on releases"; examples/reusable.yml:18 calls it "a curated pointer moved on deliberate releases". Same concept, different label. Pick one — "tag" is more conventional and is also literally what it is (a git tag).

  • Cross-file doc inconsistency: .gitea/workflows/review-reusable.yml:9 (embedded consumer example) still shows uses: steve/gadfly/.gitea/workflows/review-reusable.yml@<sha>, and line 28 still tells consumers to pin @<sha> and explicitly warns against @main, with no mention of @v1. So the README and examples/reusable.yml now promote @v1 as the primary pin with @<sha> as the immutable option, but the reusable's own header example promotes @<sha> and says nothing about @v1 — the opposite recommendation. The PR updates one consumer-facing surface but not the matching embedded example inside the reusable itself. Suggest: at least add @v1 as the primary recommendation in the embedded stub example (line 9) and update the prose on line 28 to match the new guidance.

  • Pre-existing comment duplication, not introduced but not addressed: examples/reusable.yml now repeats the same @v1/@<sha>/@main guidance in two places — the header block at lines 17–20 and the inline uses: comment at lines 52–53 — with slightly different wording. The duplication pattern existed before this PR (it duplicated @<sha>/not-@main), so it isn't a regression, but since the PR touches both comments anyway it would have been a low-churn moment to consolidate to a single canonical wording (probably the inline one, since it sits next to the actual uses: field). Not a blocker.

The headline change itself (@main@v1 with @<sha> preserved as the immutable option) is clean and matches the PR's stated intent. Nothing else in the diff strikes as unclean — no dead code, no leaky abstractions, no naming surprises, no structural churn.

Performance — No material issues found

VERDICT: No material issues found

This PR is documentation-only: README.md guidance prose plus a workflow uses: ref change (@main@v1) in examples/reusable.yml. Verified both touched regions:

  • README.md:313-318 — added the reusable-workflow pinning paragraph alongside the existing image-tag guidance.
  • examples/reusable.yml:52-54uses: ref updated, comment rewritten.

Nothing in this diff touches runtime code paths, allocations, queries, loops, or any hot path. There is no efficiency-relevant change to evaluate through the Performance lens.

🧯 Error handling & edge cases — No material issues found

VERDICT: No material issues found

This PR is docs/comments-only — it changes two blocks of prose (examples/reusable.yml:14-20, examples/reusable.yml:52-53) and one paragraph (README.md:315-318). No code paths, no error paths, no nil checks, no cleanup, no boundary conditions, no I/O — nothing in the error-handling & edge-cases lens is touched.

I verified by reading examples/reusable.yml:1-70 and README.md:300-330:

  • The uses: line at examples/reusable.yml:54 is now …@v1; the surrounding secrets:/with:/concurrency: blocks are unchanged.
  • No new error paths, fallbacks, or input validation are introduced.
  • The advice is purely advisory ("avoid @main", "curated pointer moved on deliberate releases"); any preconditions about the @v1 tag actually existing belong to the release process, which is out of scope for this diff and out of my lane.

Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 1m 22s

<!-- gadfly-review:ollama:minimax-m3:cloud --> ### 🪰 Gadfly review — `minimax-m3:cloud` (ollama-cloud) **Verdict: Blocking issues found** — 5 reviewers: security, correctness, maintainability, performance, error-handling <details><summary><b>🔒 Security</b> — No material issues found</summary> Looking at this change through the 🔒 Security lens specifically. The change is documentation-only — it updates pinning guidance from `@main`/`@<sha>` to `@v1`/`@<sha>` for reusable-workflow consumers. Security-relevant aspects to check: 1. **Secret forwarding surface** — the comment correctly still warns about `secrets: inherit` handing over every repo secret; explicit forwarding is still recommended. The new guidance doesn't relax this. 2. **Tag mutability (`@v1` vs `@main` vs `@<sha>`)** — this is genuinely the security-relevant tradeoff, and the new comment explicitly: - Discourages `@main` (moves on every push — could change what runs against forwarded secrets without consumer action). - Offers `@v1` as a curated tag "moved on deliberate releases" — *less* mutable than `@main` (only moves on tagged releases), but still mutable. - Offers full `@<sha>` as the immutable option. From a security perspective, `@v1` is strictly better than `@main` (smaller attack window — attacker needs to land a `v*` tag push, not any `main` push) but strictly worse than `@<sha>` (which the comment also offers). The text is honest about this: "curated pointer moved on deliberate releases" vs "immutable pin." No claim that `@v1` equals `@<sha>`. 3. **Permissions block** — `permissions:` stays at the existing least-privilege (`contents: read`, `issues: write`, `pull-requests: write`); unchanged. 4. **Comment-author gate** — `issue_comment` still gated to `your-username`; unchanged. 5. **No new injected input, no new deserialization, no new SSRF surface** — purely a comment/ref change. One minor observation: the new `@v1` recommendation nudges consumers toward a mutable tag. A security-strict reviewer might prefer the PR to *lead* with `@<sha>` and mention `@v1` as a convenience option, since silent movement of what runs against forwarded secrets is the exact threat the original `@main`-warning called out — and `@v1` reintroduces a (smaller) version of it. But the comment does flag this honestly ("curated … moved on deliberate releases"), and `@<sha>` is still offered side-by-side. This is a recommendation/tone call, not a gap; I'll note it but not block on it. No material security issues. The diff actually improves the security posture of the recommended default (smaller mutation window than `@main`) while preserving the immutable `@<sha>` escape hatch and the explicit-secrets warning. **VERDICT: No material issues found** - No authn/authz, injection, SSRF, deserialization, or secret-handling regressions in the change. - `permissions:` block, `secrets:` explicit-forwarding guidance, and the actor gate on `issue_comment` are all unchanged. - The new pin guidance (`@v1` over `@main`) reduces — not increases — the window in which an upstream push can silently change what runs against the consumer's forwarded secrets, while still documenting `@<sha>` as the immutable option. Verified by reading `examples/reusable.yml:14–20,52–54` and `README.md:313–318`. </details> <details><summary><b>🎯 Correctness</b> — Blocking issues found</summary> **VERDICT: Blocking issues found** - **`examples/reusable.yml:54` / `README.md:317` — the advertised `@v1` mechanism does not exist in this repo.** The PR's whole pitch is that `@v1` is "gadfly's curated release tag, re-moved on deliberate releases so central swarm tuning propagates without per-consumer re-pinning." But the only release automation in the repo is `.gitea/workflows/build-image.yml`, which publishes **container image tags** (`:v1`, `:latest`, `:sha-<short>`) to `gitea.stevedudenhoeffer.com/steve/gadfly` — it never touches a **git ref**. Grep across the repo for any release script, tag-moving workflow, or `git push --force ... v1` step returns nothing (`scripts/` has only `run.sh`, `status-board.sh`, `system-prompt.txt`; `.gitea/workflows/` has only `build-image.yml`, `review-reusable.yml`, `adversarial-review.yml`). So a consumer who follows the new advice and pins `uses: steve/gadfly/.gitea/workflows/review-reusable.yml@v1` will get a `workflow_call` resolve failure unless a human manually `git tag v1 <sha> && git push --force origin v1` for every release. Until the PR also adds the release-time automation (or at least an explicit `scripts/release.sh` + a release workflow that force-moves the git `v1` tag on `v*` tag pushes), the new recommendation is a footgun: the default `examples/reusable.yml` will not run out of the box. **Fix:** add the missing automation in the same change (e.g. a `scripts/release.sh` invoked by a `release.yml` workflow on `push: tags: ['v*']` that force-moves the git `v1` ref to the new commit, mirroring how `build-image.yml` re-tags `:latest`), or hold this docs change until that exists. - **`.gitea/workflows/review-reusable.yml:9` and `:28` — internal doc is now stale and contradicts the new recommendation.** The reusable workflow's own header still tells consumers to pin `uses: ...@<sha>` (line 9: `uses: steve/gadfly/.gitea/workflows/review-reusable.yml@<sha>`) and the closing paragraph (line 28) still says "Consumers should likewise pin `uses: ...@<sha>` (not @main)" — without mentioning the `@v1` option the freshly-updated README/reusable.yml now steer consumers toward. CLAUDE.md's own maintenance rule is "the README and `examples/` … MUST be reflected … in the same change — stale docs are a bug." Three-doc rule, not two. Verified by reading `.gitea/workflows/review-reusable.yml:1-30` and grepping the repo for `@<sha>` / `@v1` / `@main` (hits in `README.md`, `examples/reusable.yml`, and `.gitea/workflows/review-reusable.yml` only). **Fix:** update the two `@<sha>` mentions in this file's header comment to the same `@v1` (with `@<sha>` offered as the alternative) so all consumer-facing docs agree. </details> <details><summary><b>🧹 Code cleanliness & maintainability</b> — Minor issues</summary> VERDICT: **Minor issues** - **`README.md:315`** — "full-stub consumers" is a newly coined compound that's never defined and only used once. `examples/reusable.yml:1` calls its stub "SLIM consumer stub" and `.gitea/workflows/review-reusable.yml:23` points consumers at "the full stub in adversarial-review.yml", so the established vocabulary is "slim" vs. "full". Hyphenating to "full-stub" reads as a new term and mildly obscures which of the two stubs is meant for the `:vN` advice. Suggest restructuring the sentence (e.g. "Pin the **full** stub to a `:vN` image tag for stability…") rather than introducing "full-stub". - **Terminology drift between the two surfaces**: `README.md:317` calls `@v1` "a curated **tag** moved on releases"; `examples/reusable.yml:18` calls it "a curated **pointer** moved on deliberate releases". Same concept, different label. Pick one — "tag" is more conventional and is also literally what it is (a git tag). - **Cross-file doc inconsistency**: `.gitea/workflows/review-reusable.yml:9` (embedded consumer example) still shows `uses: steve/gadfly/.gitea/workflows/review-reusable.yml@<sha>`, and line 28 still tells consumers to pin `@<sha>` and explicitly warns against `@main`, with no mention of `@v1`. So the README and `examples/reusable.yml` now promote `@v1` as the primary pin with `@<sha>` as the immutable option, but the reusable's own header example promotes `@<sha>` and says nothing about `@v1` — the opposite recommendation. The PR updates one consumer-facing surface but not the matching embedded example inside the reusable itself. Suggest: at least add `@v1` as the primary recommendation in the embedded stub example (line 9) and update the prose on line 28 to match the new guidance. - **Pre-existing comment duplication, not introduced but not addressed**: `examples/reusable.yml` now repeats the same `@v1`/`@<sha>`/`@main` guidance in two places — the header block at lines 17–20 and the inline `uses:` comment at lines 52–53 — with slightly different wording. The duplication pattern existed before this PR (it duplicated `@<sha>`/not-`@main`), so it isn't a regression, but since the PR touches both comments anyway it would have been a low-churn moment to consolidate to a single canonical wording (probably the inline one, since it sits next to the actual `uses:` field). Not a blocker. The headline change itself (`@main` → `@v1` with `@<sha>` preserved as the immutable option) is clean and matches the PR's stated intent. Nothing else in the diff strikes as unclean — no dead code, no leaky abstractions, no naming surprises, no structural churn. </details> <details><summary><b>⚡ Performance</b> — No material issues found</summary> **VERDICT: No material issues found** This PR is documentation-only: README.md guidance prose plus a workflow `uses:` ref change (`@main` → `@v1`) in `examples/reusable.yml`. Verified both touched regions: - `README.md:313-318` — added the reusable-workflow pinning paragraph alongside the existing image-tag guidance. - `examples/reusable.yml:52-54` — `uses:` ref updated, comment rewritten. Nothing in this diff touches runtime code paths, allocations, queries, loops, or any hot path. There is no efficiency-relevant change to evaluate through the Performance lens. </details> <details><summary><b>🧯 Error handling & edge cases</b> — No material issues found</summary> **VERDICT: No material issues found** This PR is docs/comments-only — it changes two blocks of prose (`examples/reusable.yml:14-20`, `examples/reusable.yml:52-53`) and one paragraph (`README.md:315-318`). No code paths, no error paths, no nil checks, no cleanup, no boundary conditions, no I/O — nothing in the error-handling & edge-cases lens is touched. I verified by reading `examples/reusable.yml:1-70` and `README.md:300-330`: - The `uses:` line at `examples/reusable.yml:54` is now `…@v1`; the surrounding `secrets:`/`with:`/`concurrency:` blocks are unchanged. - No new error paths, fallbacks, or input validation are introduced. - The advice is purely advisory ("avoid `@main`", "curated pointer moved on deliberate releases"); any preconditions about the `@v1` tag actually existing belong to the release process, which is out of scope for this diff and out of my lane. </details> <sub>Automated adversarial review by Gadfly. Advisory only — does not block merge. · ⏱️ reviewed in 1m 22s</sub>
steve added 1 commit 2026-06-28 04:15:31 +00:00
docs: align review-reusable.yml header comments with the @v1 recommendation
Build & push image / build-and-push (pull_request) Successful in 6s
09d04de619
PR #12's own review flagged that the reusable's own header still said pin
@<sha>/@main while the example+README now recommend @v1. Update the header
to recommend @v1 (or @<sha>) consistently.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
steve merged commit 8f69e71311 into main 2026-06-28 04:17:19 +00:00
steve deleted branch docs/recommend-v1 2026-06-28 04:17:19 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: steve/gadfly#12