Skip to content

Add CI check to enforce capability limits#1043

Open
pelletier wants to merge 10 commits intov2from
claude/enforce-capability-limits-7dlaB
Open

Add CI check to enforce capability limits#1043
pelletier wants to merge 10 commits intov2from
claude/enforce-capability-limits-7dlaB

Conversation

@pelletier
Copy link
Copy Markdown
Owner

Summary

  • Adds a capability_baseline.json file capturing the current set of capabilities (FILES, REFLECT, MODIFY_SYSTEM_STATE, UNANALYZED) for all packages
  • Adds a GitHub Actions workflow that runs Google's capslock tool to detect if any PR introduces new capabilities
  • The check fails if any package gains a capability not present in the baseline (e.g., adding network access to the core library)

How it works

The capslock tool performs static analysis to determine what system-level capabilities (file access, network, syscalls, etc.) each package uses. The compare mode diffs the current state against the checked-in baseline and returns a non-zero exit code if new capabilities are detected.

To intentionally add a new capability, update capability_baseline.json by running:

go install github.com/google/capslock/cmd/capslock@latest
capslock -packages=./... -output=json -granularity=package > capability_baseline.json

Test plan

  • Verified capslock -output=compare returns exit code 0 against the baseline locally
  • CI workflow runs successfully on this PR

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn

claude added 10 commits March 24, 2026 01:40
Adds a capability baseline file and a GitHub Actions workflow that
uses Google's capslock tool to detect if any new capabilities (file
access, network, syscalls, etc.) are introduced by code changes.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
Replace the full JSON baseline with a simple text file listing capability
names per package. Add caps.sh script to generate and check the baseline.
Document in CONTRIBUTING.md and AGENTS.md that PRs increasing capabilities
are unlikely to be accepted.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
The baseline was generated with Go 1.24 and capslock v0.3.1. Pin
both in CI to ensure consistent analysis results, since different
Go versions can change which capabilities capslock detects.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
Rework caps.sh to detect new capabilities rather than requiring an
exact match, so the baseline works across Go versions. Add a
forbidden capabilities list (UNSAFE_POINTER, NETWORK, CGO, EXEC)
that will always fail the check. Use Go 1.26 and capslock@latest
in CI.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
Go 1.26 with capslock reports CAPABILITY_UNSAFE_POINTER for most
packages (likely from stdlib unsafe usage in reflect). Add it to
the baseline so CI passes, and remove it from the forbidden list.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
go-toml has no direct unsafe imports. Go 1.26 causes capslock to
report CAPABILITY_UNSAFE_POINTER because it traces through stdlib
internals (reflect -> unsafe). Use -capabilities flag to exclude
it from analysis, and keep it on the forbidden list so any actual
unsafe usage in go-toml code would still be caught at review time.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
Capslock reports CAPABILITY_UNSAFE_POINTER as a false positive with
Go 1.26 because it traces through unclassified stdlib reflect
functions (Append, Copy, MakeMap, MakeSlice, New, Zero) into
reflect internals that use unsafe.Pointer. This is not a real
capability of go-toml — it has zero direct unsafe imports.

Instead of using capslock's -capabilities flag (which would hide
real unsafe usage too), filter CAPABILITY_UNSAFE_POINTER from the
comparison and add a direct source check: grep for "unsafe" imports
in go-toml's own .go files. This catches actual unsafe usage while
ignoring the false positive from stdlib.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
Only analyze the go-toml/v2 library package (./), not ./... which
included cmd/ binaries. The library itself only needs REFLECT and
UNANALYZED — FILES and MODIFY_SYSTEM_STATE were from the CLI tools.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
Now that capslock is scoped to just the library package (.),
CAPABILITY_UNSAFE_POINTER no longer appears as a false positive.
Add it to FORBIDDEN_CAPS instead, and remove the source-level
unsafe import check and all the grep -v filtering.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
Go 1.26 changes how capslock traces through stdlib internals
(reflect, encoding/json), causing it to report UNSAFE_POINTER for
any package that uses reflection. This is a transitive artifact —
go-toml does not import "unsafe" directly. Include it in the
baseline so the check passes on both Go 1.24 and 1.26, and remove
it from FORBIDDEN_CAPS.

https://claude.ai/code/session_01HwDXpKevFLhE5EfrR6JrBn
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.

2 participants