Skip to content

Integrate vetted fixes from open upstream PRs (page 2) - #5

Merged
adri22235 merged 12 commits into
integration/page1-fixesfrom
integration/page2-fixes
Oct 2, 2026
Merged

adri22235 merged 12 commits into
integration/page1-fixesfrom
integration/page2-fixes

Conversation

@adri22235

Copy link
Copy Markdown
Owner

Summary

Applies the sound fixes from the second page of open pull requests in anthropics/claude-code. Original authorship is kept on every commit. Stacked on the page 1 branch, so the overlaps with it are resolved here.

Applied (12 commits; numbers are upstream PRs)

  • 82335, 82320: the GCP and AWS gateway setup.sh no longer exit silently without gcloud or abort on macOS bash 3.2
  • 82059: poppler-utils in the devcontainer, so PDFs can be read
  • 81576: plugins/README.md describes the current security-guidance hooks
  • 81421: the bash-sandbox settings example fails closed where the sandbox is unavailable (failIfUnavailable checked against CLI 2.1.287)
  • 81262: the Statsig workflow logs closed issues as closures, not creations
  • 81261: /clean_gone handles worktree paths with spaces
  • 80508: auto-close-duplicates reads every page of comments and reactions
  • 83374: MessageDisplay hook guidance in the hook-development skill (hook checked against CLI 2.1.287)
  • 81423: the devcontainer firewall also filters IPv6, which bypassed the allowlist on dual-stack networks
  • 81673: an optional firewall domain that fails to resolve no longer aborts setup
  • 80495: /ralph-loop passes the prompt as text, so $() and backticks in it are not run as shell code

Merge work

  • 83374: the skill's name: line (changed on page 1) was kept next to the PR's new description:.
  • 81673 on top of 81423: the domain lists follow main, which no longer allowlists statsig.anthropic.com (the PR added it back as optional). The AAAA lookup from 81423 now follows the same optional/required rule as the A lookup, so a failed dig cannot abort setup for an optional domain.

Not applied

  • 84138: adds a function whose body is only pass; it does nothing
  • 84364: makes hookify deny every tool call on any error. Combined with the import bug fixed in this fork's fourth PR, that would block every tool; its output also lacks hookEventName
  • 82987: removes the executable bit from 25 scripts, including hooks that run directly, and adds a stray proposal document
  • 81500: the "404" walkthrough link resolves, and to the AWS-specific page whose § sections the scripts follow; the replacement is a general overview
  • 80353: exit 1 in a README snippet meant to be pasted would close the reader's shell
  • 81426: turns on venv bootstrapping on Windows; could not be tested here
  • 81672, 81670: the same hookify fixes as this fork's fourth PR (81672 puts the package registration in a shared _bootstrap.py, a cleaner layout than mine)
  • 82981, 83738, 82794: unrelated project code, analysis documents, unrelated history
  • 82358, 80883: new plugins, not fixes

Test plan

  • Firewall: ran the merged init-firewall.sh with stubbed iptables, ip6tables, ipset, dig and curl. All domains resolving gives v4 and v6 rules with a final REJECT on each; an optional domain with no record or a failing dig is skipped with a warning; an unresolvable required domain exits 1; a host without IPv6 adds no v6 rules. Not run with real netfilter
  • /ralph-loop: a prompt containing $(touch …) and backticks is stored literally and nothing runs; positional arguments still work; --max-iterations ten is rejected
  • /clean_gone step 3, run in a scratch repo: a gone branch's worktree at a path with spaces is removed and the branch deleted
  • bun build scripts/auto-close-duplicates.ts succeeds; settings JSON and workflow YAML parse; both gateway scripts pass bash -n
  • Not tested: real macOS bash 3.2, a real gcloud-less run, the Statsig workflow (needs the upstream secret)

🤖 Generated with Claude Code

https://claude.ai/code/session_01LoLAv3aLaRJocsRMcjFbpv


Generated by Claude Code

Yyunozor and others added 12 commits October 2, 2026 16:02
…sing

Line 31 runs a gcloud command substitution under set -euo pipefail. Without
gcloud on PATH it exits 127 and takes the script with it, so the PROJECT_ID
check on line 80 never runs and the user gets no output at all. The AWS
example already guards the same construct with || true.
${DIST_SHA256,,} is a bash 4 case-modification expansion. macOS ships bash
3.2 as /bin/bash, so the line aborts the script with "bad substitution"
before it reaches its own argument checks. Replace it with printf | tr,
pinned to LC_ALL=C so BSD tr cannot fail the script on a stray non-UTF-8
byte under set -e.
The Read tool silently fails on PDFs without poppler-utils, which is
currently undocumented and missing from default container setups.
This PR adds poppler-utils to the .devcontainer provisioning to
ensure PDF rendering works out-of-the-box in containerized environments.

Closes anthropics#23704
…ndbox unavailable

The settings-bash-sandbox.json example is documented as 'Bash tool must
run inside of sandbox', but without failIfUnavailable Claude Code falls
back to running commands unsandboxed (with a warning) whenever the
sandbox cannot initialize - including on all native Windows hosts and
Linux hosts without bubblewrap. Add failIfUnavailable: true to match the
managed-enforcement configuration recommended in the sandboxing docs,
and document the platform constraint in the README.

Co-Authored-By: Claude Fable 5 <[email protected]>
Both reads used GitHub's default page size of 30 and never followed
pagination, unlike the issues list in the same script and every list
call in sweep.ts. A thumbs-down past the first 30 reactions, or human
replies after a dupe notice sitting at comment position 30, were
invisible to the guards, so issues auto-closed despite objections.

Add a githubRequestAllPages helper (per_page=100, follows pages until a
short page) and use it for both reads.

Fixes anthropics#80506
init-firewall.sh only configured iptables, so on dual-stack Docker
networks all IPv6 traffic bypassed the allowlist entirely - a hole in a
script whose documented purpose is default-deny egress for running
Claude Code with reduced supervision.

This mirrors the IPv4 posture for IPv6:
- default-DROP policies with loopback, DNS, SSH-response, link-local,
  and ICMPv6 (neighbor discovery) allowances
- an allowed-domains-v6 ipset (family inet6) populated from GitHub
  meta's IPv6 ranges and AAAA records of the existing allowlist domains
- fast REJECT (icmp6-adm-prohibited) for everything else so blocked
  IPv6 attempts fall back to IPv4 instead of hanging
- a curl -6 negative verification alongside the existing checks

All ip6tables usage is gated behind a capability probe: on hosts with
IPv6 disabled in the kernel, ip6tables cannot operate and there is no
IPv6 traffic to filter, so the script skips IPv6 rules with a warning
instead of hard-failing container startup under set -e.

Co-Authored-By: Claude Fable 5 <[email protected]>
The /ralph-loop command substituted $ARGUMENTS directly into the
auto-executed shell line, so the user's prompt text was parsed as shell
code. Any prompt containing an apostrophe (Bob's), a semicolon, $(...),
or a newline made the setup command fail its permission check (or fail
to parse) before the loop ever started:

  Error: Shell command permission check failed for pattern ...
  This Bash command contains multiple operations.

With permission checks bypassed, $(...) in a prompt would even execute.

Feed $ARGUMENTS to setup-ralph-loop.sh via a quoted heredoc on stdin
instead, so prompt text is never shell-parsed, and parse the
--max-iterations / --completion-promise options textually in the
script. Direct argv invocation still works. The state file format is
unchanged, so stop-hook.sh is unaffected.

Fixes anthropics#16037
… fails to resolve

init-firewall.sh runs under `set -e` and exits 1 as soon as any domain in the
allowlist fails to resolve. Since statsig.anthropic.com stopped resolving, that
single NXDOMAIN aborts the whole script: the ipset is left half-populated, the
default DROP policies are never applied, and the devcontainer fails to start
with exit code 1.

A telemetry or marketplace endpoint disappearing should not be able to break
container startup. The domain list is split into required domains, which still
fail loudly because the container is useless without them, and optional ones,
which are skipped with a warning and summarized at the end so the reason for a
later connection failure stays visible.

Invalid (non-IPv4) DNS answers get the same treatment: hard error for required
domains, skip with a warning otherwise.

Verified with a stubbed `dig`/`ipset`:

  statsig.anthropic.com unresolvable
    before: "ERROR: Failed to resolve statsig.anthropic.com", exit 1
    after:  warning, remaining domains still added, exit 0
  api.anthropic.com unresolvable (required)
    after:  "ERROR: Failed to resolve required domain api.anthropic.com", exit 1
  all domains resolvable
    after:  unchanged behaviour, exit 0

shellcheck clean.

Fixes anthropics#55623

Merged onto the IPv6 change (upstream PR 81423) and current main: the domain
lists follow main, which no longer allowlists statsig.anthropic.com, and the
AAAA lookup applies the same rule as the A lookup (a dig failure or a bad
address skips an optional domain instead of aborting).
@adri22235
adri22235 marked this pull request as ready for review October 2, 2026 16:14
@adri22235
adri22235 merged commit fbf75bc into integration/page1-fixes Oct 2, 2026
2 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.

8 participants