chore: install sfw in agent image (#1577)

* chore: install sfw in agent image

* feat: prompt agent to vet new dependencies before adding
This commit is contained in:
John Kennedy 2026-06-19 15:39:09 -07:00 • committed by GitHub
parent 0f842e26a0
commit e599166e5a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 55 additions and 9 deletions

View file

@ -64,7 +64,8 @@ RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y "nodejs=${NODEJS_VERSION}" \
&& rm -rf /var/lib/apt/lists/* \
&& corepack enable \
&& corepack prepare "yarn@${YARN_VERSION}" --activate
&& corepack prepare "yarn@${YARN_VERSION}" --activate \
&& npm i -g sfw
ENV GO_VERSION=1.23.5
@ -81,6 +82,7 @@ RUN echo "=== Installed versions ===" \
&& uv --version \
&& node --version \
&& yarn --version \
&& sfw --version \
&& go version \
&& docker --version \
&& git --version \

View file

@ -244,8 +244,12 @@ If you encounter missing dependencies, install them using the appropriate packag
- Use the correct package manager for the project; skip if installation fails.
- Only install dependencies if the task requires it.
- Before any package install, ensure Socket Firewall Free (`sfw`) is available with `command -v sfw`. If missing, install it with `npm i -g sfw`; if that fails, report the failure and skip the install.
- Prefix every package-manager command that fetches packages from a registry with `sfw` (for example: `sfw npm ci`, `sfw pnpm install`, `sfw pip install -r requirements.txt`, `sfw uv pip install -e .`, `sfw poetry install`). Do not run bare install commands.
- Before ADDING a new dependency the project does not already declare, first confirm the task cannot be solved with the standard library or a package already in the project's manifest/lockfile. Prefer reusing what is already there.
- Vet any genuinely new package before adding it: it should be actively maintained (a recent release, responsive issues, more than a single maintainer, steady downloads), free of known unpatched CVEs (check with `npm audit` / `pip-audit` or the GitHub advisory database), and under a permissive license (MIT, Apache-2.0, BSD). Do not add abandoned, single-source, or unlicensed packages.
- Pin or bound every newly added dependency to a specific version in the project's manifest; never add a floating or unpinned dependency.
- You cannot pause to ask for approval mid-task, so call out every dependency you add in the PR description — the package name, why it is needed, its maintenance/security status, and the alternatives you considered — so a human reviewer can veto it. This vetting is complementary to the `sfw` runtime firewall below: vetting screens out poorly-maintained or risky packages, `sfw` blocks actively-malicious ones at install time.
- Before any supported package install, ensure Socket Firewall Free (`sfw`) is available with `command -v sfw`. If missing, install it with `npm i -g sfw`; if that fails, report the failure and skip the protected install.
- Prefix supported package-manager commands that fetch packages from a registry with `sfw`: npm/yarn/pnpm, pip/uv, and cargo (for example: `sfw npm ci`, `sfw pnpm install`, `sfw pip install -r requirements.txt`, `sfw uv pip install -e .`, `sfw cargo fetch`). For unsupported package managers such as Poetry, run the normal documented install command without `sfw`.
- Always ensure dependencies are installed before running a script that might require them."""

View file

@ -109,10 +109,11 @@ Call `publish_review` once at the end.
Dependency installs during review: only install packages when needed to verify
the PR. Before any install, check `command -v sfw`; if missing, install Socket
Firewall Free with `npm i -g sfw`. Prefix registry-fetching installs with
`sfw` (for example, `sfw npm ci`, `sfw pnpm install`,
`sfw pip install -r requirements.txt`, `sfw uv pip install -e .`).
Do not run bare install commands.
Firewall Free with `npm i -g sfw`. Prefix supported registry-fetching installs
with `sfw`: npm/yarn/pnpm, pip/uv, and cargo (for example, `sfw npm ci`,
`sfw pnpm install`, `sfw pip install -r requirements.txt`,
`sfw uv pip install -e .`). For unsupported package managers such as Poetry,
run the normal documented install command without `sfw`.
If `publish_review` returns `unresolvable_findings`, do NOT retry with the
same args — call `update_finding(status="resolved", note="...")` on those ids, or fix
@ -232,6 +233,16 @@ carefully before reaching for unchanged code.
that is anchored to a changed line — these are mandatory repo rules, not
style nits, so a violation is a legitimate finding even when it would
otherwise look like a convention nit.
8. **New dependencies.** When the diff adds a dependency to a manifest or
lockfile (`package.json`, `pyproject.toml`, `requirements*.txt`,
`Cargo.toml`, `go.mod`, etc.), file a finding anchored to that changed
line when the new dependency is either (a) unpinned/floating — no specific
or bounded version — or (b) un-vetted: abandoned or single-maintainer, a
known unpatched CVE, or a missing/non-permissive license. The failure mode
is concrete (floating deps cause non-reproducible builds and supply-chain
drift; un-vetted deps add security/licensing exposure), so this is a
legitimate finding, not a style nit. A dependency that is already pinned and
from a healthy, permissively-licensed source is fine — do not file.
Use `add_finding` to record each candidate. Every finding must include a
concise generated `title` that names the failure mode in roughly 4-10 words;

View file

@ -49,7 +49,20 @@ def test_construct_system_prompt_includes_socket_firewall_dependency_guidance()
assert "npm i -g sfw" in prompt
assert "sfw npm ci" in prompt
assert "sfw uv pip install -e ." in prompt
assert "Do not run bare install commands" in prompt
assert "sfw cargo fetch" in prompt
assert "unsupported package managers such as Poetry" in prompt
assert "normal documented install command without `sfw`" in prompt
assert "sfw poetry" not in prompt
def test_construct_system_prompt_includes_dependency_vetting_guidance() -> None:
prompt = construct_system_prompt(working_dir="/workspace")
assert "Vet any genuinely new package before adding it" in prompt
assert "standard library or a package already in the project's manifest/lockfile" in prompt
assert "permissive license" in prompt
assert "never add a floating or unpinned dependency" in prompt
assert "call out every dependency you add in the PR description" in prompt
def test_construct_system_prompt_identifies_own_repo() -> None:

View file

@ -136,7 +136,23 @@ def test_reviewer_system_prompt_includes_socket_firewall_dependency_guidance() -
assert "npm i -g sfw" in prompt
assert "sfw npm ci" in prompt
assert "sfw uv pip install -e ." in prompt
assert "Do not run bare install commands" in prompt
assert "supported registry-fetching installs" in prompt
assert "unsupported package managers such as Poetry" in prompt
assert "normal documented install command without `sfw`" in prompt
assert "sfw poetry" not in prompt
def test_reviewer_system_prompt_includes_dependency_vetting_guidance() -> None:
prompt = reviewer._reviewer_system_prompt(
"/workspace/repo",
repo_owner="acme",
repo_name="repo",
pr_number=42,
)
assert "New dependencies." in prompt
assert "unpinned/floating" in prompt
assert "missing/non-permissive license" in prompt
assert "not a style nit" in prompt
def test_finding_reply_context_wraps_reply_as_untrusted_data() -> None: