Skip to content

feat(tcfeed): show what the scanner actually does, before asking - #125

Merged
ralyodio merged 1 commit into
masterfrom
worktree-tcfeed-demo
Aug 13, 2026
Merged

feat(tcfeed): show what the scanner actually does, before asking#125
ralyodio merged 1 commit into
masterfrom
worktree-tcfeed-demo

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Refs #120.

The number this is about

Of the 24 open requests, none has ever run a scan.

19 of 24 — ours: waiting for the maintainer to approve the run
 5 of 24 — ours: no runs

GitHub withholds workflow runs from first-time contributors, so every maintainer who opened one of these saw a pending or red check and no output whatsoever. The offer was "here is a scanner for your pull requests" and the demonstration had never once executed — 0 for 24.

That explains nine straight declines better than any wording did, and no amount of rewriting the pitch would have touched it. Two of the nine said as much in different words: Haven's maintainer and discord.go's both suggested a concrete finding would land better than a workflow.

What changes

The request now carries the output of a real run against the repository. It happens while the clone is already on disk, and before our own files are written, so it describes their tree rather than the workflow being added to it. The issue points at it, since the issue is what gets read first.

### What it does on this repository

@profullstack/threatcrush@0.11.0 scan .
152 files in 1.8s — 1 finding(s): 1 medium
confidence: 0 evidence, 1 pattern

What it deliberately is not

A findings dump. prBody() has always refused to quote findings at somebody as if they were defects, and this project's own sample is the reason — every such claim in it was false. Sending a maintainer a list of likely-false positives is worse than sending nothing.

So it reports what the run did — files, seconds, counts, and the confidence tier the CLI itself assigns — and says plainly that none of it is a claim:

None of that is a claim about your code, and I have not verified any of it. confidence: pattern means a regex matched and nothing more; expect false positives in that tier.

That is a fact about the scanner, not about their code, and it is the honest half of what a maintainer wanted to see.

Failure is silence. A scan that breaks, hangs, or exceeds TCFEED_DEMO_TIMEOUT (default 120s) omits the section rather than blocking the request or guessing at a number. Exit 1 is treated as a result, not a failure — that is "findings at or above --fail-on", and the JSON is on stdout either way.

Verified against real repositories

tsc --strict --noEmit clean. Both branches of the output exercised end to end via --dry-run:

With findingsdheerajshenoy/lektra:

@profullstack/threatcrush@0.11.0 scan .
152 files in 1.8s — 1 finding(s): 1 medium
confidence: 0 evidence, 1 pattern

Clean treeDuckdevv/Slowducksort:

@profullstack/threatcrush@0.11.0 scan .
4 files in 1.2s — 0 finding(s)

Nothing flagged. That is the whole report — the comment on a pull request would say the same.

🤖 Generated with Claude Code

Refs #120.

The most damning number in the experiment so far: of 24 open requests,
none has ever run a scan. Nineteen sit at "waiting for the maintainer to
approve the run" and five have no runs at all, because GitHub withholds
workflow runs from first-time contributors. Every maintainer who looked
saw a pending or red check and no output whatsoever.

The offer was "here is a scanner for your pull requests" and the
demonstration had never once executed. That explains nine straight
declines better than any wording did, and no amount of rewriting the pitch
would have touched it.

So the request now carries the output of a real run against the
repository, produced while the clone is already on disk and before our own
files are written, so it describes their tree rather than the workflow
being added to it.

What it deliberately is not is a findings dump. prBody() has always
refused to quote findings at somebody as if they were defects, and this
project's own sample is the reason: every such claim in it was false. So
this reports what the run did — files, seconds, counts, and the confidence
tier the CLI itself assigns — and says plainly that none of it is a claim
and that `confidence: pattern` means a regex matched and nothing more. A
clean tree says so in two lines.

Failure is silence: a scan that breaks, hangs or exceeds
TCFEED_DEMO_TIMEOUT omits the section rather than blocking the request or
guessing at a number.

Verified against two real repositories:

  152 files in 1.8s — 1 finding(s): 1 medium
  confidence: 0 evidence, 1 pattern

  4 files in 1.2s — 0 finding(s)

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

Copy link
Copy Markdown

ThreatCrush Security Scan

67 finding(s)

HIGH/CRITICAL: 11 | MEDIUM: 55 | LOW: 1

Severity Rule Location
HIGH secret-aws-access-key prd/0003-detect-hardcoded-secrets-before-they-are-committed-or-served.md:126
HIGH sh-eval-expansion .githooks/pre-commit:26
HIGH sh-remote-script-execution apps/web/public/install.sh:272
HIGH sh-remote-script-execution apps/web/public/install.sh:320
HIGH secret-generic-credential modules/spend-guard/config/example.conf.toml:13
HIGH secret-generic-credential modules/spend-guard/README.md:84
HIGH secret-generic-credential PRD.md:268
HIGH tls-verification-disabled prd/0004-find-dangerous-code-patterns-without-pretending-to-be-a-compiler.md:121
HIGH tls-verification-disabled prd/0004-find-dangerous-code-patterns-without-pretending-to-be-a-compiler.md:122
HIGH sh-remote-script-execution scripts/smoke-test.sh:46
HIGH sh-remote-script-execution scripts/smoke-test.sh:47
MEDIUM insecure-temp-file .githooks/commit-msg:16
MEDIUM insecure-temp-file .githooks/post-commit:20
MEDIUM js-shell-exec-interpolation apps/cli/src/commands/init.ts:70
MEDIUM js-shell-exec-interpolation apps/cli/src/commands/init.ts:79
MEDIUM js-shell-exec-interpolation apps/cli/src/commands/service.ts:88
MEDIUM js-shell-exec-interpolation apps/cli/src/commands/service.ts:111
MEDIUM sql-template-interpolation apps/cli/src/core/state.ts:121
MEDIUM sql-template-interpolation apps/cli/src/core/state.ts:125
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:31
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:33
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:34
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:35
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:36
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:43
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:49
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:56
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:63
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:82
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:84
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:85
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:93
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:98
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:105
MEDIUM js-shell-exec-interpolation apps/cli/src/daemon/firewall/adapters.ts:112
MEDIUM js-shell-exec-interpolation apps/cli/src/index.ts:419
MEDIUM js-unescaped-html-sink apps/web/src/app/about/page.tsx:180
MEDIUM js-unescaped-html-sink apps/web/src/app/about/page.tsx:184
MEDIUM js-open-redirect apps/web/src/app/auth/login/page.tsx:50
MEDIUM js-unescaped-html-sink apps/web/src/app/blog/[slug]/page.tsx:125
MEDIUM js-unescaped-html-sink apps/web/src/app/blog/[slug]/page.tsx:153
MEDIUM js-unescaped-html-sink apps/web/src/app/blog/[slug]/page.tsx:157
MEDIUM js-unescaped-html-sink apps/web/src/app/get-whitepaper/page.tsx:346
MEDIUM js-unescaped-html-sink apps/web/src/app/layout.tsx:211
MEDIUM js-unescaped-html-sink apps/web/src/app/layout.tsx:215
MEDIUM js-unescaped-html-sink apps/web/src/app/layout.tsx:219
MEDIUM js-unescaped-html-sink apps/web/src/app/page.tsx:120
MEDIUM js-unescaped-html-sink apps/web/src/app/store/[slug]/page.tsx:107
MEDIUM js-open-redirect apps/web/src/components/funding/FundingClient.tsx:97
MEDIUM manifest-install-lifecycle-script package.json:24

…and 17 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit 0b1727d into master Aug 13, 2026
11 checks passed
@ralyodio
ralyodio deleted the worktree-tcfeed-demo branch August 13, 2026 14:27
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