Skip to content

feat(tcfeed): add pr --all, the last scan worst first - #116

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

feat(tcfeed): add pr --all, the last scan worst first#116
ralyodio merged 1 commit into
masterfrom
worktree-tcfeed-pr-all

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor
tcfeed pr --all --dry-run
tcfeed pr --all

--all is the flag this deliberately did not have. The rails around it are the substance of the change, because the reason it did not have one has not gone anywhere: bulk unsolicited pull requests are against GitHub's acceptable use policy however good the workflow is, and an account that sends them stops being able to send anything. Worth stating plainly — the first maintainer to answer one of these closed it (rasterm/rasterm#3).

What --all means

The run whose table is still on the screen — not every repository the cache has ever seen. The cache holds 76 of them and none of that was being looked at when --all was typed. main() writes the ranked table to lastrun, --all reads it back, so the two cannot disagree about what "all" meant.

Worst first, through one shared ranked() now used by both the table and the file. Two orderings that drift is the sort of bug nobody notices until the wrong repository has been written to, and it matters because the cap truncates — taking the worst three of twenty-five has to mean the top of the table.

Too-big, archived and vanished repositories cannot appear. They are skipped before a row is ever added, so lastrun cannot offer --all something the scan itself declined to clone.

The cap changes shape rather than going away

Named repositories were typed, so exceeding TCFEED_PR_MAX is still an error. --all was one word, so it truncates instead — and says out loud how many it left behind, because a run that quietly did three of twenty-five reads exactly like a run that did all of them:

tcfeed: 5 in the last run, taking the worst 3.
  2 left for a later run, or raise TCFEED_PR_MAX.

TCFEED_PR_PAUSE (default 20s) spaces the requests that actually open. Forking, pushing and opening in a tight loop is the shape abuse detection watches for, and being throttled mid-run leaves half a fork behind. Skips wait for nothing.

Verified

tsc --strict clean, every path exercised:

Case Result
--all, no prior scan refuses, explains that --all is the table a scan prints
--all foo/bar refuses as ambiguous
5 in lastrun, cap 3 taking the worst 3 + 2 left for a later run
already-asked repos all three skipped, including rasterm/rastermalready asked — closed
real scan → lastrun written in exactly table order, 3-critical repo first

🤖 Generated with Claude Code

The flag this deliberately did not have. The rails around it are the
substance of the change, because the reason it did not have one has not
gone anywhere: bulk unsolicited pull requests are against GitHub's
acceptable use policy however good the workflow is, and an account that
sends them stops being able to send anything.

--all is the run whose table is still on the screen, not every
repository the cache has ever seen - the cache holds months of them and
none of that was being looked at when --all was typed. main() writes
the ranked table to `lastrun` and --all reads it back, so the two can
never disagree about what "all" meant.

Worst first, through one shared `ranked()` now used by both the table
and the file. Two orderings that drift is the sort of bug nobody
notices until the wrong repository has been written to, and it matters
here precisely because the cap truncates: taking the top three of
twenty-five has to mean the top of the table.

Too-big, archived and vanished repositories cannot appear. They are
skipped before a row is ever added, so `lastrun` cannot offer --all
something the scan itself declined to clone.

The cap changes shape rather than going away. Named repositories were
typed, so exceeding the cap is still an error; --all was one word, so
it truncates instead - and says out loud how many it left behind,
because a run that quietly did three of twenty-five reads exactly like
a run that did all of them.

TCFEED_PR_PAUSE (default 20s) spaces the requests that actually open.
Forking, pushing and opening in a tight loop is the shape abuse
detection watches for, and being throttled mid-run leaves half a fork
behind. Skips wait for nothing.

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 e7c8f2c into master Aug 13, 2026
11 checks passed
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