Skip to content

ROX-33916: add devcontainer with Claude Code agent for autonomous collector development#3118

Open
robbycochran wants to merge 2 commits intomasterfrom
rc-claude-dev
Open

ROX-33916: add devcontainer with Claude Code agent for autonomous collector development#3118
robbycochran wants to merge 2 commits intomasterfrom
rc-claude-dev

Conversation

@robbycochran
Copy link
Copy Markdown
Collaborator

@robbycochran robbycochran commented Mar 19, 2026

Summary

Adds a devcontainer-based development environment where a Claude Code agent can autonomously implement, build, test, and submit changes to collector. The agent works inside an isolated container based on the collector-builder image with all C++ dependencies pre-installed.

This gives you a secure workflow to run claude with a select set of tools, the benefit of CI feedback, and with permission checks disabled.

Workflow

Interactive

  • Local development on collector in an interactive session, with a ready to go development environment.
  • Creates a standard claude container that can be run with permission checks disabled on your host of choice (laptop or cloud vm).
  • Repository skills provided needed tooling to develop.
.devcontainer/run.sh --interactive

Autonomous (hands-off):
Agent implements, pushes via MCP, creates PR, monitors CI until green.

.devcontainer/run.sh "add unit tests for ExternalIPsConfig"

What's included

Devcontainer (.devcontainer/)

  • Dockerfile — extends collector-builder:master with Claude Code, Go, Node.js, gcloud CLI, clang-format, bubblewrap (sandboxing), ripgrep, fd
  • devcontainer.json — works with both VSCode and CLI, forwards Vertex AI + GitHub credentials
  • run.sh — launcher script with multiple modes:
    • run.sh "task" — autonomous: implement, PR, CI loop
    • run.sh --interactive — isolated clone + TUI for manual control
    • run.sh --local — edit working tree directly
    • run.sh --shell — shell into the container
  • entrypoint.sh — creates .claude/ dirs, registers GitHub MCP server via PAT
  • init-firewall.sh — optional iptables network restrictions (Vertex AI, GitHub, registries)

Skills (.claude/skills/)

  • /task — implement a change: edit, build, test, format, commit. Stops after commit, no push.
  • /watch-ci — push via GitHub MCP, create PR, monitor CI, fix failures, loop until green

Security model

  • No SSH keys in container — git push fails at auth, only GitHub MCP can push
  • GitHub PAT scoped to stackrox/collector (Contents, PRs, Actions)
  • MCP deny rules — merge, delete, fork, create-repo, trigger-actions blocked globally
  • Read-only mounts — gcloud credentials, gitconfig
  • Isolated clone — agent works on a git clone --local in /tmp, not the user's checkout
  • bubblewrap — Claude Code's built-in command sandboxing
  • Branch protection — agent can push to branches but cannot merge to master

Agent guide (CLAUDE.md)

  • Build commands, key paths, testing rules
  • Git rules: use skills, don't create branches, don't push unless /watch-ci

Prerequisites

  • Docker (Docker Desktop, OrbStack, or Colima)
  • gcloud auth login && gcloud auth application-default login
  • Vertex AI env vars (CLAUDE_CODE_USE_VERTEX, GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_LOCATION)
  • GITHUB_TOKEN — fine-grained PAT for stackrox/collector

Test plan

  • Image builds on arm64 Mac
  • Collector compiles inside container (cmake configure + build)
  • 17/17 unit tests pass inside container
  • Claude Code authenticates to Vertex AI
  • Claude Code responds to prompts and uses tools
  • /task skill discovered and invocable
  • Git clone isolation works (separate from host checkout)
  • /watch-ci pushes via GitHub MCP and creates PR
  • CI monitoring loop detects failures and iterates
  • Autonomous end-to-end run completes

@robbycochran robbycochran requested a review from a team as a code owner March 19, 2026 06:17
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 27.38%. Comparing base (c8c0181) to head (c62aa5b).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3118   +/-   ##
=======================================
  Coverage   27.38%   27.38%           
=======================================
  Files          95       95           
  Lines        5427     5427           
  Branches     2548     2548           
=======================================
  Hits         1486     1486           
  Misses       3214     3214           
  Partials      727      727           
Flag Coverage Δ
collector-unit-tests 27.38% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@robbycochran robbycochran changed the title Claude dev environment feat: add devcontainer with Claude Code agent for autonomous collector development Mar 19, 2026
# Register GitHub MCP server if token is available
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
if ! claude mcp add-json github \
'{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer '"$GITHUB_TOKEN"'","X-MCP-Toolsets":"context,repos,pull_requests,issues,actions,git"}}' \
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be a little cleaner/safer to interpolate the GITHUB_TOKEN into the json via jq

jq -n --arg token "$GITHUB_TOKEN" \
    '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":("Bearer " + $token),"X-MCP-Toolsets":"context,repos,pull_requests,issues,actions,git"}}'

mkdir -p /home/dev/.claude/debug /home/dev/.commandhistory

# Set defaults so Claude Code doesn't prompt on startup
claude config set --global theme dark 2> /dev/null || true
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as a light-mode heathen, can we make this configurable with default to dark? 😅

echo "Task: $TASK"
echo "---"

trap on_exit EXIT
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this trap should probably be after line 245 in case any of the subsequent commands fail and we bypass the cleanup

- If build fails, fix and retry
5. Test: `ctest --no-tests=error -V --test-dir cmake-build`
- If tests fail, fix and retry
6. Format: `clang-format --style=file -i <changed .cpp/.h files>`
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might be able to make this more general purpose if we teach claude to use the pre-commit hooks, and should mean we're covered if it changes any non-C++ code


4. **Safety limits**:
- Maximum 6 CI cycles (about 3 hours of monitoring)
- If exceeded, update PR body and stop
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once a cycle has been stopped, how would we restart it? It'd be ideal if we could add a comment with guidance on the specific problem and then prompt claude to fix and restart the cycle. Not sure if this is possible though

dfbf8345b feat: add devcontainer and Claude Code agent development environment
125265f23 docs: add Vertex AI setup and devcontainer build instructions to CLAUDE.md
446368067 feat: add launcher script with worktree isolation and GitHub PAT support
255973f63 feat: use official GitHub MCP server, fix run.sh, add bubblewrap
186b64f91 refactor: convert skills to collector-dev plugin with scoped tool permissions
654e94d16 feat: create branch and draft PR upfront, tighten iterate permissions
2c55d55db feat: add watch-ci skill for CI monitoring loop
c5b99277f feat: add end-to-end task skill with CI monitoring loop
2e595c66c fix: load collector-dev plugin via --plugin-dir flag
495175e07 feat: stream agent activity to stdout in autonomous mode
37ae0c778 feat: add --local mode for debugging without worktree or PR
8d676b290 feat: add --headless mode (worktree + stream-json, no PR)
310f54b8a fix: initialize submodules in worktree after creation
3bc345bb6 fix: only init required submodules, drop --recursive
4026f1bbb fix: headless mode now invokes /collector-dev:task skill like default mode
bbfc92dee feat: add preflight checks with clear error messages
02cd22383 refactor: remove gh CLI dependency, agent creates PR via GitHub MCP
63927219d refactor: move skills from plugin to standalone, simplify CLAUDE.md
a56fcf0b9 refactor: switch worktree to clone, consolidate to 2 skills, fix audit issues
c7d94e59a fix: move git push deny to container-only settings
97333c681 security: remove SSH mount, git push blocked by lack of credentials
27f9c5643 fix: set clone remote to GitHub URL instead of local path
9ca06ebb9 refactor: switch back to worktrees, mount .git at same absolute path
dffd017f2 perf: shallow submodule checkout in worktrees (--depth 1)
0b48869be perf: mount submodules from main repo instead of cloning per worktree
c7235b886 feat: make submodule mounting optional via --symlink-submodules
1ed07b9c7 feat: add --branch flag, use /tmp/collector-worktrees/ for worktrees
1ec7baa6a fix: reject --branch with --local mode
3a5bae34c fix: mount .git read-write so git commit works in container
ae67afece security: mount .git read-only with worktree subdir read-write
4de75efbb fix: set theme and verbose defaults in entrypoint to skip startup prompts
75951d2c3 fix: chmod worktree git dir for container uid mismatch
4a890e4fd fix: use chmod a+rwX to fix directory permissions in worktree git dir
d98fa6120 fix: mount .git read-write, partial ro/rw overlay doesn't work
cb28d8977 security: remove SYS_PTRACE/NET_ADMIN/NET_RAW caps, drop --symlink-submodules
d54640991 feat: specify GitHub MCP toolsets via X-MCP-Toolsets header
cdc273455 feat: watch-ci updates PR body with agent status after each CI cycle
94df7c938 docs: add MCP Context Protector integration plan
1c4e4e6c9 fix: autonomous mode inlines task instructions instead of invoking /task skill
deba75adc feat: add /dev-loop skill combining task + watch-ci + PR comment handling
2943f398b feat: allow specifying skill in autonomous mode, default to /dev-loop
36c9709c0 fix: remove local keyword from case branch (not a function)
0c1222999 docs: update MCP security plan — recommend mcp-watchdog over mcp-context-protector
7d156e3ee fix: push branch from host before launching autonomous agent
1bcb0215b fix: only push branch in autonomous /dev-loop mode, not for explicit skills
0903b5dff feat: TUI is now default for all modes, --no-tui for stream-json
e058a9283 docs: clarify push_files usage in dev-loop and watch-ci skills
587f879da docs: add devcontainer README with GitHub PAT permissions and setup guide
ba617318a fix: shfmt formatting and shellcheck SC2064 warning in run.sh
d1620ff8c fix: shfmt formatting — use 4-space indent per .editorconfig
3ff6a8415 fix: address PR review feedback for devcontainer scripts
@github-actions
Copy link
Copy Markdown

/retest collector-on-push

@robbycochran robbycochran changed the title feat: add devcontainer with Claude Code agent for autonomous collector development ROX-33916: add devcontainer with Claude Code agent for autonomous collector development Mar 30, 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.

3 participants