Skip to content

feat(show-dont-tell): require an image or preview URL when rendered paths change - #78

Merged
mark-brannan merged 6 commits into
mainfrom
claude/show-dont-tell
Oct 17, 2026
Merged

mark-brannan merged 6 commits into
mainfrom
claude/show-dont-tell

Conversation

@mark-brannan

@mark-brannan mark-brannan commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

show-dont-tell

Reusable check for the "yes, full stop" ruling (RCA round 2, item 3): in an opted-in repo, a PR touching a rendered path must carry an image or a preview URL in its description, else red. Opt-in is a per-repo file; no file, no check.

Caller (the trigger types make a description edit re-run it):

on: { pull_request: { types: [opened, edited, synchronize, reopened] } }
jobs:
  show-dont-tell: { permissions: { contents: read, pull-requests: read }, uses: mark-brannan/.github/.github/workflows/show-dont-tell.yml@main }

Opt-in file .github/show-dont-tell.yml in the calling repo:

paths:
  - "web/**"
  - "screenshots/goldens/**"
urls:            # optional: prefixes of this repo's preview URLs
  - https://preview.example.com/

Satisfied by an inline image (![..](..), <img src>, a user-attachments upload) or a link starting with one of the urls: prefixes. With urls: absent only an image counts. An image or URL inside a code span, a fence or an HTML comment (a template placeholder) does not count. The body is read live from the API. The summary names the matched paths when red; "no rendered path touched" when green with no match.

Cost: node built-ins only, no install step; its own job. Measured: show-dont-tell-tests 4 s per push, the whole CI run green: https://github.com/mark-brannan/.github/actions/runs/39008635039 . The reusable workflow reads the opt-in file at the PR base (a PR cannot exempt itself), and costs a few seconds in a caller (no install, no checkout of the caller).

Pencil:

  • risk · a preview URL counts only when the opt-in file names its prefix under urls:; without urls: only an image counts. The first draft accepted any https link off github.com, and the agent attribution link https://claude.com/claude-code in every agent-written body met it, so the check would never have fired on an agent PR. Undo: revert 047ba9c. decisions log

Head: c0eae14

🤖 Generated with Claude Code
🤖 claude-sonnet-5-5 · medium · 2f08b81b, then claude-fable-5-1 · - · 4371c500, then claude-fable-5-1 · - · 22d27a82

…s shows an image or preview URL

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Repository: mark-brannan/coderabbit/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 7a54d303-6ecd-4f8c-9cd6-19e7442f25f1
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Duplication: 2 new clones, 4 new repeated literals

Whole tree Base Head
Clones (jscpd, 5+ lines, 50+ tokens) 8 10
Duplicated lines 72 (1.46%) 87 (1.66%)
Repeated literals (20+ characters, 2+ files) 18 20

New clones

Lines Copy Copy
8 .github/workflows/golden-diff.yml:113-120 .github/workflows/show-dont-tell.yml:67-74
7 .github/scripts/golden-diff.mjs:82-88 .github/scripts/show-dont-tell.mjs:20-26

New repeated literals

Literal Files Newly in
$GITHUB_STEP_SUMMARY 7 .github/workflows/show-dont-tell.yml
mark-brannan/.github 5 .github/workflows/show-dont-tell.yml
Accept: application/vnd.github.raw 2 .github/scripts/show-dont-tell.mjs
screenshots/goldens/** 2 .github/workflows/show-dont-tell.yml

Scanned the whole tree, e1b177b against 0482d5b. A measurement, not a gate.
Every clone and literal is in the run's duplication artifact: duplication run

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Complexity: +33 across 19 functions

File Function Cyclomatic Δ Cognitive
.github/scripts/show-dont-tell.mjs:13 globToRegExp — → 6 +6 — → 14
.github/scripts/show-dont-tell.mjs:35 parseConfig — → 6 +6 — → 9
.github/scripts/show-dont-tell.mjs:74 report — → 5 +5 — → 6
.github/scripts/show-dont-tell.mjs:30 (anonymous) — → 1 +1 — → —
.github/scripts/show-dont-tell.mjs:30 (anonymous)#2 — → 1 +1 — → 0
.github/scripts/show-dont-tell.mjs:70 (anonymous)#3 — → 1 +1 — → —
.github/scripts/show-dont-tell.mjs:70 (anonymous)#4 — → 1 +1 — → 0
.github/scripts/show-dont-tell.mjs:76 (anonymous)#5 — → 1 +1 — → 0
.github/scripts/show-dont-tell.mjs:28 matchPaths — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:6 (anonymous) — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:20 (anonymous)#2 — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:25 (anonymous)#3 — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:31 (anonymous)#4 — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:35 (anonymous)#5 — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:50 (anonymous)#6 — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:57 (anonymous)#7 — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:65 (anonymous)#8 — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:73 (anonymous)#9 — → 1 +1 — → 0
.github/scripts/show-dont-tell.test.mjs:7 m — → 1 +1 — → 0
All metrics
Function Metric Before After
.github/scripts/show-dont-tell.mjs · globToRegExp ccn — 6
.github/scripts/show-dont-tell.mjs · globToRegExp cognitive — 14
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.N1 — 66.0
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.N2 — 43.0
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.bugs — 0.18
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.difficulty — 21.5
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.effort — 12636.9
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.length — 109.0
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.n1 — 21.0
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.n2 — 21.0
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.vocabulary — 42.0
.github/scripts/show-dont-tell.mjs · globToRegExp halstead.volume — 587.76
.github/scripts/show-dont-tell.mjs · globToRegExp length — 14
.github/scripts/show-dont-tell.mjs · globToRegExp mi.mi_original — 93.71
.github/scripts/show-dont-tell.mjs · globToRegExp mi.mi_sei — 60.11
.github/scripts/show-dont-tell.mjs · globToRegExp mi.mi_visual_studio — 54.8
.github/scripts/show-dont-tell.mjs · globToRegExp nesting — 4
.github/scripts/show-dont-tell.mjs · globToRegExp nloc — 14
.github/scripts/show-dont-tell.mjs · globToRegExp params — 1
.github/scripts/show-dont-tell.mjs · globToRegExp tokens — 126
.github/scripts/show-dont-tell.mjs · parseConfig ccn — 6
.github/scripts/show-dont-tell.mjs · parseConfig cognitive — 9
.github/scripts/show-dont-tell.mjs · parseConfig halstead.N1 — 83.0
.github/scripts/show-dont-tell.mjs · parseConfig halstead.N2 — 49.0
.github/scripts/show-dont-tell.mjs · parseConfig halstead.bugs — 0.18
.github/scripts/show-dont-tell.mjs · parseConfig halstead.difficulty — 16.9
.github/scripts/show-dont-tell.mjs · parseConfig halstead.effort — 12522.74
.github/scripts/show-dont-tell.mjs · parseConfig halstead.length — 132.0
.github/scripts/show-dont-tell.mjs · parseConfig halstead.n1 — 20.0
.github/scripts/show-dont-tell.mjs · parseConfig halstead.n2 — 29.0
.github/scripts/show-dont-tell.mjs · parseConfig halstead.vocabulary — 49.0
.github/scripts/show-dont-tell.mjs · parseConfig halstead.volume — 741.14
.github/scripts/show-dont-tell.mjs · parseConfig length — 14
.github/scripts/show-dont-tell.mjs · parseConfig mi.mi_original — 92.5
.github/scripts/show-dont-tell.mjs · parseConfig mi.mi_sei — 58.37
.github/scripts/show-dont-tell.mjs · parseConfig mi.mi_visual_studio — 54.1
.github/scripts/show-dont-tell.mjs · parseConfig nesting — 2
.github/scripts/show-dont-tell.mjs · parseConfig nloc — 14
.github/scripts/show-dont-tell.mjs · parseConfig params — 1
.github/scripts/show-dont-tell.mjs · parseConfig tokens — 139
.github/scripts/show-dont-tell.mjs · report ccn — 5
.github/scripts/show-dont-tell.mjs · report cognitive — 6
.github/scripts/show-dont-tell.mjs · report halstead.N1 — 67.0
.github/scripts/show-dont-tell.mjs · report halstead.N2 — 67.0
.github/scripts/show-dont-tell.mjs · report halstead.bugs — 0.18
.github/scripts/show-dont-tell.mjs · report halstead.difficulty — 15.82
.github/scripts/show-dont-tell.mjs · report halstead.effort — 12142.08
.github/scripts/show-dont-tell.mjs · report halstead.length — 134.0
.github/scripts/show-dont-tell.mjs · report halstead.n1 — 17.0
.github/scripts/show-dont-tell.mjs · report halstead.n2 — 36.0
.github/scripts/show-dont-tell.mjs · report halstead.vocabulary — 53.0
.github/scripts/show-dont-tell.mjs · report halstead.volume — 767.54
.github/scripts/show-dont-tell.mjs · report length — 5
.github/scripts/show-dont-tell.mjs · report mi.mi_original — 103.09
.github/scripts/show-dont-tell.mjs · report mi.mi_sei — 73.84
.github/scripts/show-dont-tell.mjs · report mi.mi_visual_studio — 60.29
.github/scripts/show-dont-tell.mjs · report nesting — 1
.github/scripts/show-dont-tell.mjs · report nloc — 5
.github/scripts/show-dont-tell.mjs · report params — 3
.github/scripts/show-dont-tell.mjs · report tokens — 122
.github/scripts/show-dont-tell.mjs · (anonymous) ccn — 1
.github/scripts/show-dont-tell.mjs · (anonymous) length — 1
.github/scripts/show-dont-tell.mjs · (anonymous) nesting — 0
.github/scripts/show-dont-tell.mjs · (anonymous) nloc — 1
.github/scripts/show-dont-tell.mjs · (anonymous) params — 0
.github/scripts/show-dont-tell.mjs · (anonymous) tokens — 7
.github/scripts/show-dont-tell.mjs · (anonymous)#2 ccn — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#2 cognitive — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.N1 — 3.0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.N2 — 5.0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.bugs — 0.0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.difficulty — 1.25
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.effort — 25.85
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.length — 8.0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.n1 — 2.0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.n2 — 4.0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.vocabulary — 6.0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 halstead.volume — 20.68
.github/scripts/show-dont-tell.mjs · (anonymous)#2 length — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#2 mi.mi_original — 155.02
.github/scripts/show-dont-tell.mjs · (anonymous)#2 mi.mi_sei — 148.05
.github/scripts/show-dont-tell.mjs · (anonymous)#2 mi.mi_visual_studio — 90.65
.github/scripts/show-dont-tell.mjs · (anonymous)#2 nesting — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 nloc — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#2 params — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#2 tokens — 10
.github/scripts/show-dont-tell.mjs · (anonymous)#3 ccn — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#3 length — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#3 nesting — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#3 nloc — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#3 params — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#3 tokens — 7
.github/scripts/show-dont-tell.mjs · (anonymous)#4 ccn — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#4 cognitive — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.N1 — 3.0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.N2 — 5.0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.bugs — 0.0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.difficulty — 1.25
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.effort — 25.85
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.length — 8.0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.n1 — 2.0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.n2 — 4.0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.vocabulary — 6.0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 halstead.volume — 20.68
.github/scripts/show-dont-tell.mjs · (anonymous)#4 length — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#4 mi.mi_original — 155.02
.github/scripts/show-dont-tell.mjs · (anonymous)#4 mi.mi_sei — 148.05
.github/scripts/show-dont-tell.mjs · (anonymous)#4 mi.mi_visual_studio — 90.65
.github/scripts/show-dont-tell.mjs · (anonymous)#4 nesting — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 nloc — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#4 params — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#4 tokens — 10
.github/scripts/show-dont-tell.mjs · (anonymous)#5 ccn — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#5 cognitive — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.N1 — 1.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.N2 — 2.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.bugs — 0.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.difficulty — 1.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.effort — 3.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.length — 3.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.n1 — 1.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.n2 — 1.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.vocabulary — 2.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 halstead.volume — 3.0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 length — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#5 mi.mi_original — 165.06
.github/scripts/show-dont-tell.mjs · (anonymous)#5 mi.mi_sei — 162.53
.github/scripts/show-dont-tell.mjs · (anonymous)#5 mi.mi_visual_studio — 96.52
.github/scripts/show-dont-tell.mjs · (anonymous)#5 nesting — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 nloc — 1
.github/scripts/show-dont-tell.mjs · (anonymous)#5 params — 0
.github/scripts/show-dont-tell.mjs · (anonymous)#5 tokens — 8
.github/scripts/show-dont-tell.mjs · matchPaths ccn — 1
.github/scripts/show-dont-tell.mjs · matchPaths cognitive — 0
.github/scripts/show-dont-tell.mjs · matchPaths halstead.N1 — 19.0
.github/scripts/show-dont-tell.mjs · matchPaths halstead.N2 — 20.0
.github/scripts/show-dont-tell.mjs · matchPaths halstead.bugs — 0.03
.github/scripts/show-dont-tell.mjs · matchPaths halstead.difficulty — 6.0
.github/scripts/show-dont-tell.mjs · matchPaths halstead.effort — 1072.88
.github/scripts/show-dont-tell.mjs · matchPaths halstead.length — 39.0
.github/scripts/show-dont-tell.mjs · matchPaths halstead.n1 — 9.0
.github/scripts/show-dont-tell.mjs · matchPaths halstead.n2 — 15.0
.github/scripts/show-dont-tell.mjs · matchPaths halstead.vocabulary — 24.0
.github/scripts/show-dont-tell.mjs · matchPaths halstead.volume — 178.81
.github/scripts/show-dont-tell.mjs · matchPaths length — 4
.github/scripts/show-dont-tell.mjs · matchPaths mi.mi_original — 120.88
.github/scripts/show-dont-tell.mjs · matchPaths mi.mi_sei — 99.0
.github/scripts/show-dont-tell.mjs · matchPaths mi.mi_visual_studio — 70.69
.github/scripts/show-dont-tell.mjs · matchPaths nesting — 0
.github/scripts/show-dont-tell.mjs · matchPaths nloc — 4
.github/scripts/show-dont-tell.mjs · matchPaths params — 2
.github/scripts/show-dont-tell.mjs · matchPaths tokens — 28
.github/scripts/show-dont-tell.test.mjs · (anonymous) ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous) cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.N1 — 64.0
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.N2 — 68.0
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.bugs — 0.13
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.difficulty — 11.83
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.effort — 7733.72
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.length — 132.0
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.n1 — 8.0
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.n2 — 23.0
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.vocabulary — 31.0
.github/scripts/show-dont-tell.test.mjs · (anonymous) halstead.volume — 653.95
.github/scripts/show-dont-tell.test.mjs · (anonymous) length — 13
.github/scripts/show-dont-tell.test.mjs · (anonymous) mi.mi_original — 95.28
.github/scripts/show-dont-tell.test.mjs · (anonymous) mi.mi_sei — 61.96
.github/scripts/show-dont-tell.test.mjs · (anonymous) mi.mi_visual_studio — 55.72
.github/scripts/show-dont-tell.test.mjs · (anonymous) nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous) nloc — 13
.github/scripts/show-dont-tell.test.mjs · (anonymous) params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous) tokens — 130
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.N1 — 24.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.N2 — 17.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.bugs — 0.03
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.difficulty — 5.67
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.effort — 907.7
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.length — 41.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.n1 — 6.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.n2 — 9.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.vocabulary — 15.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 halstead.volume — 160.18
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 length — 4
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 mi.mi_original — 121.92
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 mi.mi_sei — 100.29
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 mi.mi_visual_studio — 71.3
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 nloc — 4
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#2 tokens — 49
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.N1 — 28.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.N2 — 19.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.bugs — 0.04
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.difficulty — 7.12
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.effort — 1470.88
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.length — 47.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.n1 — 9.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.n2 — 12.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.vocabulary — 21.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 halstead.volume — 206.44
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 length — 5
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 mi.mi_original — 116.98
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 mi.mi_sei — 93.17
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 mi.mi_visual_studio — 68.41
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 nloc — 5
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#3 tokens — 55
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.N1 — 13.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.N2 — 8.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.bugs — 0.01
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.difficulty — 3.5
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.effort — 287.16
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.length — 21.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.n1 — 7.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.n2 — 8.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.vocabulary — 15.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 halstead.volume — 82.04
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 length — 3
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 mi.mi_original — 130.05
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 mi.mi_sei — 112.03
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 mi.mi_visual_studio — 76.06
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 nloc — 3
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#4 tokens — 25
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.N1 — 76.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.N2 — 94.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.bugs — 0.16
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.difficulty — 11.75
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.effort — 10630.55
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.length — 170.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.n1 — 8.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.n2 — 32.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.vocabulary — 40.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 halstead.volume — 904.73
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 length — 14
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 mi.mi_original — 92.62
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 mi.mi_sei — 58.02
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 mi.mi_visual_studio — 54.16
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 nloc — 14
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#5 tokens — 171
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.N1 — 26.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.N2 — 32.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.bugs — 0.04
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.difficulty — 5.71
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.effort — 1407.88
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.length — 58.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.n1 — 5.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.n2 — 14.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.vocabulary — 19.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 halstead.volume — 246.38
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 length — 6
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 mi.mi_original — 113.11
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 mi.mi_sei — 87.58
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 mi.mi_visual_studio — 66.14
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 nloc — 6
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#6 tokens — 58
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.N1 — 32.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.N2 — 40.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.bugs — 0.05
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.difficulty — 6.67
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.effort — 2074.53
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.length — 72.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.n1 — 5.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.n2 — 15.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.vocabulary — 20.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 halstead.volume — 311.18
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 length — 7
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 mi.mi_original — 109.4
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 mi.mi_sei — 82.23
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 mi.mi_visual_studio — 63.97
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 nloc — 7
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#7 tokens — 72
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.N1 — 34.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.N2 — 38.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.bugs — 0.07
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.difficulty — 8.94
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.effort — 2989.55
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.length — 72.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.n1 — 8.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.n2 — 17.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.vocabulary — 25.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 halstead.volume — 334.36
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 length — 7
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 mi.mi_original — 109.02
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 mi.mi_sei — 81.69
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 mi.mi_visual_studio — 63.76
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 nloc — 7
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#8 tokens — 73
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 ccn — 1
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 cognitive — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.N1 — 114.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.N2 — 85.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.bugs — 0.23
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.difficulty — 17.31
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.effort — 18082.51
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.length — 199.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.n1 — 11.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.n2 — 27.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.vocabulary — 38.0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 halstead.volume — 1044.34
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 length — 11
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 mi.mi_original — 95.78
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 mi.mi_sei — 62.58
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 mi.mi_visual_studio — 56.01
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 nesting — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 nloc — 11
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 params — 0
.github/scripts/show-dont-tell.test.mjs · (anonymous)#9 tokens — 211
.github/scripts/show-dont-tell.test.mjs · m ccn — 1
.github/scripts/show-dont-tell.test.mjs · m cognitive — 0
.github/scripts/show-dont-tell.test.mjs · m halstead.N1 — 5.0
.github/scripts/show-dont-tell.test.mjs · m halstead.N2 — 7.0
.github/scripts/show-dont-tell.test.mjs · m halstead.bugs — 0.01
.github/scripts/show-dont-tell.test.mjs · m halstead.difficulty — 2.1
.github/scripts/show-dont-tell.test.mjs · m halstead.effort — 75.6
.github/scripts/show-dont-tell.test.mjs · m halstead.length — 12.0
.github/scripts/show-dont-tell.test.mjs · m halstead.n1 — 3.0
.github/scripts/show-dont-tell.test.mjs · m halstead.n2 — 5.0
.github/scripts/show-dont-tell.test.mjs · m halstead.vocabulary — 8.0
.github/scripts/show-dont-tell.test.mjs · m halstead.volume — 36.0
.github/scripts/show-dont-tell.test.mjs · m length — 1
.github/scripts/show-dont-tell.test.mjs · m mi.mi_original — 152.14
.github/scripts/show-dont-tell.test.mjs · m mi.mi_sei — 143.89
.github/scripts/show-dont-tell.test.mjs · m mi.mi_visual_studio — 88.97
.github/scripts/show-dont-tell.test.mjs · m nesting — 0
.github/scripts/show-dont-tell.test.mjs · m nloc — 1
.github/scripts/show-dont-tell.test.mjs · m params — 2
.github/scripts/show-dont-tell.test.mjs · m tokens — 16

Measured 2 changed files, e1b177b against 0482d5b. A measurement, not a gate.
Every metric is in the run's complexity artifact: complexity run

@claude

claude Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Claude finished @mark-brannan's task in 1m 13s —— View job


Review: show-dont-tell

There are three inline findings. Two of them let a PR that touches a rendered path go green without showing anything.

# Where What goes wrong
1 show-dont-tell.mjs:89 The opt-in file is read from the PR's own checkout. A PR can delete it, or empty its paths:, and go green. Fix: read it at the base commit through the contents API.
2 show-dont-tell.mjs:43 List items with no indent (paths:\n- "web/**", which is valid YAML) parse to an empty list. The check then passes silently. Fix: change \s+ to \s*.
3 show-dont-tell.mjs:51 ![](..) counts even inside backticks. This PR's own description passes this way, and so does the red message's hint if it is pasted back. Fix: remove code spans and fenced blocks before scanning.

Security checks (the ones this repo asks for):

  • Permissions are read-only.
  • No secrets are used beyond github.token.
  • The PR body and file contents are handled only inside node, never put into run:.
  • ci-gate gains a dependency and loses none.
  • actions/checkout@v7 is pinned by tag, not by commit SHA, but every other workflow here does the same, so this PR doesn't introduce it.

Not verified: I couldn't run the test suite because node needs approval in this job, so the three failure cases above come from reading the code, not from a run.

Comment thread .github/scripts/show-dont-tell.mjs Outdated
Comment thread .github/scripts/show-dont-tell.mjs Outdated
Comment thread .github/scripts/show-dont-tell.mjs
@mergify mergify Bot removed the awaiting-human label Oct 17, 2026
…ted lists, ignore code spans

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@claude

claude Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Claude finished @mark-brannan's task in 24s —— View job


Review: show-dont-tell (after the fix push)

The three earlier findings are fixed in this push: config read at the base SHA, unindented list items accepted, and code spans and fences stripped before the image scan. I did not re-raise them. There is one new finding, inline at show-dont-tell.mjs:67.

# Where What goes wrong
1 show-dont-tell.mjs:67 The URL scan reads text, not the stripped shown. A URL quoted in backticks or a fence still counts as a preview URL, so the code-span fix covers images but not URLs. Fix: shown.match(...), plus a test.

Security checks:

  • Permissions are read-only.
  • No secrets are used beyond github.token.
  • The PR body and config contents are handled only inside node, never put into run:.
  • ci-gate gains a dependency and loses none.
  • actions/checkout@v7 is pinned by tag, which matches the other workflows in this repo.

Not verified: I did not run the test suite. This review comes from reading the code.

Comment thread .github/scripts/show-dont-tell.mjs Outdated
…n either

The code-span strip covered the image scan only; the URL scan still read
the raw body, so a fenced example URL counted as a preview.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@claude

claude Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Claude finished @mark-brannan's task in 16s —— View job


Review: show-dont-tell (after c347521)

No new findings. The one open item from the last review, the URL scan reading text instead of shown, is fixed in this push: scanBody now scans shown for URLs (show-dont-tell.mjs), with tests added. I did not re-raise the earlier threads.

Security checks:

  • Permissions are read-only (contents: read, pull-requests: read in the caller).
  • No secrets are used beyond github.token.
  • The PR body and config contents are handled only inside node. run: interpolates env vars only, so there is no injection path.
  • The opt-in file is read at base.sha, so a PR can't exempt itself.
  • ci-gate gains show-dont-tell-tests and loses no dependency.
  • actions/checkout@v7 is pinned by tag, which matches the other workflows in this repo.

Not verified: node needs approval in this job, so I did not run the test suite. This review comes from reading the code.

… prefix

Without urls:, any https link off github.com satisfied the check, and
every agent-written PR body carries one: the attribution link
https://claude.com/claude-code. The check would never have fired on an
agent PR. Now only an image counts unless urls: names the repo's preview
prefixes; the red message drops the link hint when none are named.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@claude

claude Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Claude finished @mark-brannan's task in 17s —— View job


Review: show-dont-tell (after 047ba9c)

One finding, on the PR description, not the code. No inline comments.

# Where What goes wrong
1 PR description It still says urls: is "optional; absent = any https link not on github.com". Since 047ba9c, an absent urls: means only an image counts. The title and the line "Satisfied by an inline image or a preview URL" also imply a link always works. Fix: change the opt-in comment to urls: # optional; absent = only an image counts and say a preview URL counts only when urls: names its prefix.

The code, tests and the workflow header comment agree with each other. The new scanBody tests cover the claude.com attribution link, http:// against an https:// prefix, and the red-message wording both with and without urls:.

Security checks:

  • Permissions are read-only.
  • No secrets are used beyond github.token.
  • The PR body and config contents are handled only inside node, never put into run:.
  • The opt-in file is read at base.sha.
  • 047ba9c narrows what passes and adds no new input path.

Not verified: I did not run the test suite. node needs approval in this job, so this review comes from reading the diff.

@mergify mergify Bot removed the awaiting-human label Oct 17, 2026
@mark-brannan

Copy link
Copy Markdown
Owner Author

🤖 Critical review. One hole the earlier passes missed, fixed in 047ba9c: without urls: any https link off github.com satisfied the check, and every agent-written PR body carries one, the attribution link https://claude.com/claude-code. Verified by calling scanBody on this PR's own footer: it returned kind: 'url'. Now a URL counts only when the opt-in file names its prefix; without urls: only an image counts. Tests updated, suite 9/9. 97708f2 fixes a test I pushed red in 047ba9c.

🤖 claude-fable-5-1 · - · 4371c500

…own either

A PR template's placeholder (<!-- drop a screenshot here: ![..](..) -->)
survives into every body written over it and counted as an image. Comments
are stripped with code spans and fences before the scan, with tests.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@mark-brannan

Copy link
Copy Markdown
Owner Author

🤖 Critical review, second pass. One gap the earlier passes missed, fixed in c0eae14: an image or URL inside an HTML comment counted as shown, so a PR template's placeholder (<!-- drop a screenshot here: ![..](..) -->) would have satisfied the check on every body written over it. Comments are now stripped with code spans and fences before the scan, with four tests. Suite 9/9 locally, CI green on c0eae14. Nothing needs the user; queuing to merge.

🤖 claude-fable-5-1 · - · 22d27a82

@mark-brannan
mark-brannan merged commit eb7307e into main Oct 17, 2026
17 checks passed
@mergify mergify Bot removed the awaiting-human label Oct 17, 2026
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