Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This is a security-hardened Docker container that runs Claude Code with pre-inst
The container is built on Node.js 22 (LTS) with the following layers:

1. **Base System** - Debian Trixie (glibc 2.41) with hardened security settings
2. **Toolchain (npm)** - All global npm CLIs installed via `npm ci` from `tools/package.json` + `tools/package-lock.json` (sha512-integrity, exact pinned versions, no `@latest`). Bins exposed via PATH (`/opt/toolchain/node_modules/.bin`). Includes Claude Code (2.1.177), OpenSpec (1.4.1), CodeGraph (1.0.0), caveman-shrink (0.1.0), the MCP servers, and dev tools (pnpm 11.6.0, typescript 6.0.3, ts-node 10.9.2, prettier 3.8.4, eslint 10.5.0)
2. **Toolchain (npm)** - All global npm CLIs installed via `npm ci` from `tools/package.json` + `tools/package-lock.json` (sha512-integrity, exact pinned versions, no `@latest`). Bins exposed via PATH (`/opt/toolchain/node_modules/.bin`). Includes Claude Code (2.1.183), OpenSpec (1.4.1), CodeGraph (1.0.1), caveman-shrink (0.1.0), the MCP servers, and dev tools (pnpm 11.8.0, typescript 6.0.3, ts-node 10.9.2, prettier 3.8.4, eslint 10.5.0)
3. **OpenSpec** - initialized into `/workspace` at build time with telemetry disabled via `OPENSPEC_TELEMETRY=0`
4. **RTK** - Rust Token Killer; static musl binary in `/usr/local/bin` (version via `RTK_VERSION` build arg, sha256-verified); `rtk init -g --auto-patch` installs a Claude Code PreToolUse hook that rewrites Bash commands through `rtk`
5. **Caveman** - Output-compression skill for Claude Code, installed at build time via its plugin mechanism (`claude plugin install`), pinned to tag `v1.9.0`
Expand Down Expand Up @@ -205,7 +205,10 @@ different `lockfileVersion`):
```bash
docker run --rm -v "$PWD/tools:/w" -w /w node:22-trixie-slim npm install --package-lock-only
```
Pin only Node-22-compatible versions — check `npm view <pkg>@<ver> engines.node`. The build-time
After regenerating, run `npm audit` in the same `node:22` image — and, when a clean non-breaking
fix is offered, `npm audit fix --package-lock-only` — so transitive security advisories surface and
get patched instead of silently shipping. `npm install` keeps in-range pinned transitive versions,
so an already-applied patch is not downgraded by a later regen. Pin only Node-22-compatible versions — check `npm view <pkg>@<ver> engines.node`. The build-time
gate runs each dev tool's `--version` to catch an incompatible engine (this is how the earlier
pnpm 11 vs Node 20 mismatch was caught before the base was bumped to Node 22).

Expand Down Expand Up @@ -321,7 +324,7 @@ Two extra entrypoints exist beside the autonomous `run_claude.sh`; they share th
- Installed with **`--no-mcp-shrink`**: caveman's auto-registration wired `caveman-shrink` as a standalone MCP server with no upstream command, which always `✗ Failed to connect` (it is middleware, not a server). Instead `caveman-shrink` is pre-installed globally and applied as a wrapper around the codegraph MCP server (see CodeGraph / MCP Servers)
- Source: https://github.com/JuliusBrussee/caveman
- **CodeGraph** - Pre-indexed code knowledge graph (symbols, call graph, impact) served to agents over MCP (`codegraph` binary)
- Installed via `npm ci` from the locked toolchain (`@colbymchenry/codegraph@1.0.0`); also registered as the `codegraph` MCP server, wrapped by `caveman-shrink` to compress its (verbose) tool descriptions — verified `✓ Connected` (see "MCP Servers")
- Installed via `npm ci` from the locked toolchain (`@colbymchenry/codegraph@1.0.1`); also registered as the `codegraph` MCP server, wrapped by `caveman-shrink` to compress its (verbose) tool descriptions — verified `✓ Connected` (see "MCP Servers")
- **Not pure JS:** the npm package is a thin shim; the real artifact is a per-platform optionalDependency (`@colbymchenry/codegraph-linux-x64`) bundling a vendored Node 24 runtime + prebuilt binary. `codegraph --help` at build time verifies the binary runs (**verified**: the vendored Node 24 binary runs on `node:22-trixie-slim`)
- `CODEGRAPH_NO_DOWNLOAD=1` (baked-in ENV) forbids the shim's runtime fallback that fetches the binary from GitHub Releases — the binary must come from the npm registry only
- 100% local: local SQLite index (`.codegraph/codegraph.db`, FTS5), no API keys, no external services
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,13 @@ Base: `node:22-trixie-slim` (Node 22 LTS, Debian 13 / glibc 2.41). Multi-arch (a
Toolchain pinned in `tools/package.json`, locked in `tools/package-lock.json` (`npm ci`, sha512
integrity, exact versions):

- `@anthropic-ai/claude-code` (2.1.177), `@fission-ai/openspec` (1.4.1)
- `@agentclientprotocol/claude-agent-acp` (0.44.0) — ACP adapter for IDE use (Zed); reuses
- `@anthropic-ai/claude-code` (2.1.183), `@fission-ai/openspec` (1.4.1)
- `@agentclientprotocol/claude-agent-acp` (0.48.0) — ACP adapter for IDE use (Zed); reuses
the pinned `claude` binary via `CLAUDE_CODE_EXECUTABLE`
- `@colbymchenry/codegraph` (1.0.0, MCP) wrapped by `caveman-shrink` (0.1.0)
- `@colbymchenry/codegraph` (1.0.1, MCP) wrapped by `caveman-shrink` (0.1.0)
- MCP servers: `sequential-thinking`, `context7` (HTTP), `perplexity`
- caveman skill (plugin, tag `v1.9.0`)
- Dev tools: `pnpm` 11.6.0, `typescript` 6.0.3, `ts-node` 10.9.2, `prettier` 3.8.4, `eslint` 10.5.0
- Dev tools: `pnpm` 11.8.0, `typescript` 6.0.3, `ts-node` 10.9.2, `prettier` 3.8.4, `eslint` 10.5.0

GitHub-release binaries (per-arch, sha256-pinned): `rtk` (v0.42.4), `git-delta` (0.19.2).
CLI utilities: `jq`, `ripgrep`, `fd`, `tree`, `fzf`, `mc`, `gnupg`.
Expand Down
11 changes: 11 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ compromised and rotate it immediately.
- Residual gaps (documented, not yet closed): the caveman installer clones its marketplace repo at
default-branch HEAD (build-reproducibility gap, not a runtime hole), and `npm ci` does not
neutralize postinstall network fetchers in transitive dependencies.
- Known transitive advisories (`npm audit`): the toolchain ships with `form-data` and `hono`
patched (`npm audit fix --package-lock-only`, no top-level pin drift). Two high-severity
advisories remain in `@modelcontextprotocol/sdk` (≤1.25.1), pulled in transitively by
`perplexity-mcp@0.2.3` (the latest release, which pins the old SDK) — upstream marks both
"no fix available." Applicability in this image is limited: the DNS-rebinding advisory
(GHSA-w48q-cv73-mx4w) targets HTTP servers bound to localhost that accept browser origins, but
`perplexity-mcp` runs as a **stdio** server here (no listening socket); the ReDoS advisory
(GHSA-8r9q-7v3j-jr4g) requires feeding adversarial input through the SDK's parser. This is a
**deliberately accepted residual**. Closing it would mean dropping `perplexity-mcp` or forcing a
patched SDK via an npm `overrides` entry — the latter is a user-decided follow-up because it may
break `perplexity-mcp`'s SDK API usage.
- The ACP adapter pulls in `@anthropic-ai/claude-agent-sdk`, which ships its own Claude Code binary
as a per-platform optionalDependency. To avoid executing a second, separately-sourced Claude
binary, `CLAUDE_CODE_EXECUTABLE` pins the ACP path to the already-audited `claude` from the
Expand Down
Loading
Loading